如何在c ++中创建抽象类的数组

时间:2015-10-14 10:49:59

标签: c++ arrays abstract-class

我正在尝试创建一个程序,它接受食物订单并将其打印出来。我有我的基类Food,其中包含一个纯虚函数。 Class Food有2个子类PizzaDessert。我想在Food中制作一个main数组,以便当客户订购PizzaDessert时,它会存储在Food数组中。但每次我尝试,我都会收到错误。如果我想使用循环来检查客户订购的每件商品,我应该如何将这两个商品放在一起呢? 这是我的代码:

int main()
{
  Dessert d("brownie");
  Pizza p("BBQ delux");
  Food array[2] = {d,p};
}

这是我的错误消息。 (注意:get_set_price()print_food()是我的纯虚函数,它在基类中定义并在2个子类中实现)

main.cpp:37:14: error: invalid abstract type ‘Food’ for ‘array’
  Food array[2] = {d,p};

In file included from main.cpp:4:0:
Food.h:5:7: note:   because the following virtual functions are pure within ‘Food’:
 class Food
       ^

Food.h:20:15: note:     virtual void Food::get_set_price()
  virtual void get_set_price()=0;
               ^

Food.h:27:15: note:     virtual void Food::print_food()
  virtual void print_food()=0; 
               ^

main.cpp:37:22: error: cannot allocate an object of abstract type ‘Food’
  Food array[2] = {f,o};
                  ^

4 个答案:

答案 0 :(得分:15)

您不能创建抽象类的实例,但可以将具体的派生实例分配给基类的指针或引用。

int main()
{
  Dessert d("brownie");
  Pizza p("BBQ delux");
  Food* array[2] = {&d,&p};
}

然后使用array

array[0]->print_food();

答案 1 :(得分:9)

你需要引用语义,因为Food arr[2];尝试使用默认值初始化数组(这是抽象的,因此不是可构造的)。

我认为在这种情况下std::array<std::unique_ptr<Food>, 2> arr;应该是最自然的。

std::array<std::unique_ptr<Food>> arr = { new Dessert("brownie"), new Pizza("BBQ delux") };

如果您只想循环使用这两个值,我猜想使用initializer_list最简单。

for (auto f : std::initializer_list<Food*>{&d,&p})
    f->commonMemberFunction();

不幸的是,它不会仅仅从{}推断出正确的类型,但我想,可以创建一个帮助器

答案 2 :(得分:2)

从C ++ 11开始,您也可以使用std::reference_wrapper。它与@ Mykola的答案非常相似,但使用了引用:

#include <functional>  // for std::reference_wrapper

int main()
{
  Dessert d("brownie");
  Pizza p("BBQ delux");
  std::reference_wrapper<Food> array = {d, p};

  // just to see they're references, they have same memory addresses as
  // the initial variables.
  for (const Food &f : array) {
    std::cout << &f << " ";
  }
  std::cout << "\n" << &d << " " << &p << "\n";
}

不幸的是,同样的限制适用于此和带指针的版本。你需要定义局部变量,你不能在这里使用匿名对象。

这不会起作用:

  std::reference_wrapper<Food> array = {Dessert("brownie"), Pizza("BBQ delux")};

答案 3 :(得分:0)

我喜欢@Mykola回答的简单性。但是,我更喜欢以下外观:

int main()
{
  Food* array[] = {
    new Dessert("brownie"),
    new Pizza("BBQ delux")
    };
}