C ++:初始化一个指向不同类型对象的指针数组

时间:2017-06-14 06:43:24

标签: c++ arrays initialization

C ++中是否有一种语法来初始化指向不同类型对象的指针数组而无需额外的赋值?我试着在下面提供一个完整的例子。

#include "stdio.h"

class Base {
    public:
        Base(int cnt=1) : _cnt(cnt) {}
        virtual void print() { printf("?\n"); }
    protected:      
        int _cnt;       
};      

class A : public Base {     
    public:     
        A(int val, int cnt=1) : _val(val), Base(cnt) {}
        void print() override { for (int i=0; i<_cnt; i++) printf("A(%d)\n", _val);  }
    private:
        int _val;
};

class B : public Base {
    public:
        B(const char* val, int cnt=1) : _val(val), Base(cnt) {}
        void print() override { for (int i=0; i<_cnt; i++) printf("B(\"%s\")\n", _val);  }
    private:
        const char* _val;
};

//  *** I would like to combine the following statements ***
A a = { 42, 2 };
B b = { "hi there", 3 };

Base* test[] = { &a, &b };

int main() {
    for (auto *x : test) { x->print(); }
}

当我尝试

Base* test2[] = {
    &A(42, 2), 
    &B("hi there", 3),
};

我收到获取临时地址的错误。代码需要在小型嵌入式系统上运行代码,因此我尽量避免动态分配。

希望这不是常见问题...

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

你的帖子提到你想要价值语义,这意味着没有动态分配。在您提到的评论中,您的类型集已关闭。因此,您可以使用boost::variant进行闭集多态性。

using common_t = boost::variant<A, B>;

common_t arr[] = {
    A(42, 2), 
    B("hi there", 3),
};

好消息是类型不再需要具有共同基础。他们只需要尊重相同的界面(print)。您基本上用静态多态替换动态。现在,通用lambda可用于访问任何成员

for(auto &obj : arr)
  boost::apply_visitor([](auto& o) {
    o.print();
  }, obj);

答案 1 :(得分:0)

在你的例子中:

Base* test2[] = {
    &A(42, 2), 
    &B("hi there", 3),
};

AB都在数组初始值设定项的范围内实例化。它们是此范围的临时性,这就是编译器不允许您将它们存储在数组中的原因。

您应该使用智能指针动态分配对象,因为访问其范围之外的堆栈变量是不安全的。

智能指针的一个很好的例子是shared_ptrhttp://en.cppreference.com/w/cpp/memory/shared_ptr