如何使用 Base 和 Derived objects default-initialize std::vector<Base>?
How to default-initialize std::vector<Base> with Base and Derived objects?
考虑以下因素:
#include <vector>
class Base
{
public:
Base() : x(0) {}
int x;
};
class Derived : public Base
{
public:
Derived(double z0) : Base(), z(z0) {}
double z;
};
class Foo
{
public:
// How to specify a default value for parameter vec0,
// consisting of two Base objects?
Foo(std::vector<Base> vec0 = ? ? ? ) : vec(vec0) {}
std::vector<Base> vec;
};
class Bar
{
public:
// foo1.vec needs to be initialized with two Base objects.
// foo2.vec needs to be initialized with two Derived objects.
Bar() : foo1(? ? ? ), foo2(? ? ? ) {}
Foo foo1;
Foo foo2;
};
int main()
{
Bar bar;
// Code here will want to use Base class pointers to access the elements
// in bar.foo1.vec and bar.foo2.vec.
}
如何在Foo构造函数中指定一个默认参数?
在Bar
构造函数initializer list中,如何指定Base
的向量
objects 代表 foo1
,Derived
objects 代表 foo2
?
如何给这个问题起标题以便其他需要解决这个问题的人可以找到它?
How to specify a default parameter in the Foo constructor?
只需使用初始化列表语法,或者显式声明包含元素:
class Foo {
public:
Foo(std::vector<Base> vec0 = {Base(), Base()}) : vec(vec0) {}
std::vector<Base> vec;
};
或使用另一个初始化列表隐式声明:
class Foo {
public:
Foo(std::vector<Base> vec0 = {{}, {}}) : vec(vec0) {}
std::vector<Base> vec;
};
但是如果您打算创建大小为 2 的默认列表,我认为这样做更好:
class Foo {
public:
Foo() : vec(2) {}
std::vector<Base> vec;
};
In the Bar constructor initializer list, how to specify a vector of Base objects for foo1, and a vector of Derived objects for foo2?
你不能这样做。您需要使用模板或指针向量。
模板示例:
template<class V>
class Foo {
public:
Foo(std::vector<V> vec0 = {{}, {}}) : vec(vec0) {}
std::vector<V> vec;
};
class Bar {
public:
// No need to explicitly initialize foo1
Bar() : foo2({{1.},{2.}}) {}
Foo<Base> foo1;
Foo<Derived> foo2;
};
的回答很好地解释了如何使用初始化列表完成初始化。我想关注解决方案,其中 Foo
有一个指向 Base
的 向量指针。使用 std::vector<std::shared_ptr<Base>>
,您可以重写 @sklott 的解决方案,如下所示:
#include <memory> // std::shared_ptr
#include <utility> // std::move
class Foo
{
public:
Foo(std::vector<std::shared_ptr<Base>> vec0 = {
{ std::make_shared<Base>(), std::make_shared<Base>() }
}
)
: vec{ std::move(vec0) }
{}
std::vector<std::shared_ptr<Base>> vec;
};
class Bar
{
public:
Bar()
: foo1{} // calls Foo's default cont'r: initialized with two Base objects.
, foo2{ // initialized with two Derived objects.
{ std::make_shared<Derived>(1.0), std::make_shared<Derived>(1.0) }
}
{}
Foo foo1;
Foo foo2;
};
如果我们不为 Base
class 提供 virtual
析构函数,上面的代码将具有 an undefied behaviour .因此,要使其完整解决:
class Base
{
public:
Base() : x(0) {}
int x;
virtual ~Base() = default; // don't forget to provide a virtual destructor
};
考虑以下因素:
#include <vector>
class Base
{
public:
Base() : x(0) {}
int x;
};
class Derived : public Base
{
public:
Derived(double z0) : Base(), z(z0) {}
double z;
};
class Foo
{
public:
// How to specify a default value for parameter vec0,
// consisting of two Base objects?
Foo(std::vector<Base> vec0 = ? ? ? ) : vec(vec0) {}
std::vector<Base> vec;
};
class Bar
{
public:
// foo1.vec needs to be initialized with two Base objects.
// foo2.vec needs to be initialized with two Derived objects.
Bar() : foo1(? ? ? ), foo2(? ? ? ) {}
Foo foo1;
Foo foo2;
};
int main()
{
Bar bar;
// Code here will want to use Base class pointers to access the elements
// in bar.foo1.vec and bar.foo2.vec.
}
如何在Foo构造函数中指定一个默认参数?
在
Bar
构造函数initializer list中,如何指定Base
的向量 objects 代表foo1
,Derived
objects 代表foo2
?如何给这个问题起标题以便其他需要解决这个问题的人可以找到它?
How to specify a default parameter in the Foo constructor?
只需使用初始化列表语法,或者显式声明包含元素:
class Foo {
public:
Foo(std::vector<Base> vec0 = {Base(), Base()}) : vec(vec0) {}
std::vector<Base> vec;
};
或使用另一个初始化列表隐式声明:
class Foo {
public:
Foo(std::vector<Base> vec0 = {{}, {}}) : vec(vec0) {}
std::vector<Base> vec;
};
但是如果您打算创建大小为 2 的默认列表,我认为这样做更好:
class Foo {
public:
Foo() : vec(2) {}
std::vector<Base> vec;
};
In the Bar constructor initializer list, how to specify a vector of Base objects for foo1, and a vector of Derived objects for foo2?
你不能这样做。您需要使用模板或指针向量。
模板示例:
template<class V>
class Foo {
public:
Foo(std::vector<V> vec0 = {{}, {}}) : vec(vec0) {}
std::vector<V> vec;
};
class Bar {
public:
// No need to explicitly initialize foo1
Bar() : foo2({{1.},{2.}}) {}
Foo<Base> foo1;
Foo<Derived> foo2;
};
Foo
有一个指向 Base
的 向量指针。使用 std::vector<std::shared_ptr<Base>>
,您可以重写 @sklott 的解决方案,如下所示:
#include <memory> // std::shared_ptr
#include <utility> // std::move
class Foo
{
public:
Foo(std::vector<std::shared_ptr<Base>> vec0 = {
{ std::make_shared<Base>(), std::make_shared<Base>() }
}
)
: vec{ std::move(vec0) }
{}
std::vector<std::shared_ptr<Base>> vec;
};
class Bar
{
public:
Bar()
: foo1{} // calls Foo's default cont'r: initialized with two Base objects.
, foo2{ // initialized with two Derived objects.
{ std::make_shared<Derived>(1.0), std::make_shared<Derived>(1.0) }
}
{}
Foo foo1;
Foo foo2;
};
如果我们不为 Base
class 提供 virtual
析构函数,上面的代码将具有 an undefied behaviour .因此,要使其完整解决:
class Base
{
public:
Base() : x(0) {}
int x;
virtual ~Base() = default; // don't forget to provide a virtual destructor
};