如何使用基本对象和派生对象默认初始化std :: vector <Base>?

时间:2019-08-07 07:34:59

标签: c++ class c++11 inheritance stdvector

请考虑以下内容:

#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.
}
  1. 如何在Foo构造函数中指定默认参数?

  2. Bar构造函数初始化器列表中,如何指定Base的向量 foo1的对象和Derived的{​​{1}}对象的向量?

  3. 如何为这个问题加上标题,以便其他需要解决此问题的人可以找到它?

2 个答案:

答案 0 :(得分:2)

  

如何在Foo构造函数中指定默认参数?

只需使用初始化程序列表语法,即可显式声明包含元素:

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;
};
  

在Bar构造函数的初始值设定项列表中,如何为foo1指定基础对象的向量,以及为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;
};

答案 1 :(得分:2)

documentation的答案很好地说明了如何使用初始化列表进行初始化。我想重点介绍一下#' Tree Distances #' #' These datasets contain the distances between sets #' of 10-tip, 11-tip and 12-tip trees. #' #' @name treeDistances #' @keywords datasets NULL #' @rdname treeDistances "treeDistances10" #' @rdname treeDistances "treeDistances11" #' @rdname treeDistances "treeDistances12" 具有指向Foo 的指针的向量的解决方案。使用Base,您可以按以下方式重写 @sklott 的解决方案:

std::vector<std::shared_ptr<Base>>

如果我们没有为#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; }; 类提供virtual析构函数,则上述代码将具有 @sklott 。因此,要使其成为完整的解决方案:

Base