如何在 C++ 中创建抽象数组 class
how to create array of an abstract class in c++
我正在尝试创建一个接受食物订单并将其打印出来的程序。我的基础 class Food
里面有一个纯虚函数。 Class食物有2个子classPizza
和Dessert
。我正在尝试在我的 main
中创建一个 Food
数组,因此当客户订购 Pizza
或 Dessert
时,它将存储在 Food
数组中.但每次尝试时,我都会出错。如果我想使用循环遍历客户订购的每件商品,我应该如何将这两个商品放在一起?
这是我的代码:
int main()
{
Dessert d("brownie");
Pizza p("BBQ delux");
Food array[2] = {d,p};
}
这是我的错误信息。 (注意:get_set_price()
和 print_food()
是我在基础 class 中定义并在 2 个子 classes 中实现的纯虚函数)
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};
^
你需要引用语义,因为 Food arr[2];
试图用默认值初始化数组(这是抽象的,因此不可构造)。
我觉得std::array<std::unique_ptr<Food>, 2> arr;
用在这种情况下应该是最自然的
std::array<std::unique_ptr<Food>> arr = {
std::make_unique<Dessert>("brownie"),
std::make_unique<Pizza>("BBQ delux")
};
不过,如果您只想遍历这两个值,我想使用 initializer_list
是最简单的。
for (auto f : std::initializer_list<Food*>{&d,&p})
f->commonMemberFunction();
不幸的是,它不会仅从 {}
推断出正确的类型,但我想可以创建一个助手,
您不能创建抽象 classes 的实例,但您可以将具体的派生实例分配给基 class.
的指针或引用
int main()
{
Dessert d("brownie");
Pizza p("BBQ delux");
Food* array[2] = {&d,&p};
}
然后与 array
合作
array[0]->print_food();
从 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")};
我喜欢@Mykola 简单的回答。但是,我更喜欢以下外观:
int main()
{
Food* array[] = {
new Dessert("brownie"),
new Pizza("BBQ delux")
};
}
我正在尝试创建一个接受食物订单并将其打印出来的程序。我的基础 class Food
里面有一个纯虚函数。 Class食物有2个子classPizza
和Dessert
。我正在尝试在我的 main
中创建一个 Food
数组,因此当客户订购 Pizza
或 Dessert
时,它将存储在 Food
数组中.但每次尝试时,我都会出错。如果我想使用循环遍历客户订购的每件商品,我应该如何将这两个商品放在一起?
这是我的代码:
int main()
{
Dessert d("brownie");
Pizza p("BBQ delux");
Food array[2] = {d,p};
}
这是我的错误信息。 (注意:get_set_price()
和 print_food()
是我在基础 class 中定义并在 2 个子 classes 中实现的纯虚函数)
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};
^
你需要引用语义,因为 Food arr[2];
试图用默认值初始化数组(这是抽象的,因此不可构造)。
我觉得std::array<std::unique_ptr<Food>, 2> arr;
用在这种情况下应该是最自然的
std::array<std::unique_ptr<Food>> arr = {
std::make_unique<Dessert>("brownie"),
std::make_unique<Pizza>("BBQ delux")
};
不过,如果您只想遍历这两个值,我想使用 initializer_list
是最简单的。
for (auto f : std::initializer_list<Food*>{&d,&p})
f->commonMemberFunction();
不幸的是,它不会仅从 {}
推断出正确的类型,但我想可以创建一个助手,
您不能创建抽象 classes 的实例,但您可以将具体的派生实例分配给基 class.
的指针或引用int main()
{
Dessert d("brownie");
Pizza p("BBQ delux");
Food* array[2] = {&d,&p};
}
然后与 array
array[0]->print_food();
从 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")};
我喜欢@Mykola 简单的回答。但是,我更喜欢以下外观:
int main()
{
Food* array[] = {
new Dessert("brownie"),
new Pizza("BBQ delux")
};
}