你能帮我用C ++编写组合示例应用程序吗?
我需要这样的层次结构:类AppleCake继承自基类Cake,还有类CakePacket,它有4个Cakes。我写了一些代码,但问题是我不知道如何向CakePacket添加4个Cake对象。我是C ++的初学者,所以如果会有一些愚蠢的错误,我很抱歉。
#include <iostream>
using namespace std;
class Cake {
protected:
int cost;
public:
void setCostr(int a) { cost = a; }
int getCost() { return cost; }
Cake(int x) { cost = x; }
~Cake() { }
};
class AppleCake : public Cake {
int diameter;
public:
int getDiameter() { return diameter; }
AppleCake(int x, int y): Cake(x)
{ diameter = y; }
~AppleCake() { }
};
class CakePacket
{
private:
Cake *cArr;
CakePacket() { }
public:
CakePacket(Cake *x) //there have to be 4 Cake objects in CakePacket
: cArr(new Cake[4]) {};
};
最后一个问题是 - 如何创建CakePacket的对象?
稍后我将再创建一个组合,一些类将包含1个CakePacket。但我希望将1个CakePacket对象添加到其他类中是没有问题的。
感谢您的所有答案!
答案 0 :(得分:5)
因为在最后一小时没人说得对...实际上@ taylorc93是最接近的,但他仍然设法犯了错误。
所以,回到这个问题。 CakePacket应该存储Cakes,对吧? Cake
是基类,但它没有虚方法。在这种情况下,使用指针是完全没必要的,你唯一要做的就是使用一些容器。现在,您选择哪一个取决于CakePacket的预期用途。让我们以一般的方式写出来,然后:
class CakePacket {
// this can be whatever you might need; a list, set, unordered_set...
// vector is a reasonable default
vector<Cake> cakes;
public:
// We'll also need a way to add them:
void addCake(Cake cake) {
// I'm moving the parameter to avoid copying
// refer to "move semantics" to understand it deeper
cakes.push_back(std::move(cake));
}
};
瞧!你已经问过如何创建一个CakePacket,这很简单。
CakePacket cp;
cp.addCake(Cake(1));
cp.addCake(Cake(2));
cp.addCake(Cake(3));
当然,您可以将它们移动到CakePacket
的构造函数,但是......
CakePacket cp { Cake(1), Cake(2), Cake(3), Cake(4) };
如果您希望能够从类似数组的列表中创建,则需要提供带有initializer_list<Cake>
的aditional构造函数,但我会将其作为练习。 (提示:不会需要for
循环)。
这是一个学习问题,所以我不会对它挑剔,但我想指出CakePacket真正做到的事实......没有,至少在当前状态。有时,简单地使用std
容器更容易,而不是将其包装在一个全新的类型中。这样可以避免使用多余的类来污染代码,并且您会惊讶于标准库为您提供了多少功能。
如果您尝试将AppleCake存储在其中,diameter
将获得切片,即只保存公共部分。在这种情况下,您需要将指针存储到基类(使用boost::ptr_vector<Cake>
或std::vector<std::unique_ptr<Cake>>
),或使用类似Boost.Variant
的内容。
...正在存储原始指针。你必须销毁CakePacket dtor中添加的每个Cake,这很容易出错,而且根本不需要。
使用C风格的数组也相当糟糕,因为它会限制你使用固定大小。
答案 1 :(得分:0)
好的,这不是很难解决。首先,我建议使用std::vector
而不是任何数组。如果您不知道向量是什么,您可以将它们视为没有限制的数组(如果您需要扩展它以添加更多内容,则无需担心AKA)。您可以声明这样的矢量:
std::vector<the type of each object in the vector> someName
其次,这可能是一个错字,但看起来你的AppleCake
类继承自Brake
,而不是Cake
,所以如果这是一个错字,你应该解决这个问题。
现在,要将4个蛋糕添加到CakePacket
,我建议您更改CakePacket
构造函数以获取它应该保留多少个Cakes的int。然后,你可以将它们添加到蛋糕中:
CakePacket::CakePacket(int numCakes){
std::vector<Cake> cakes;
for (int i = 0; i < numCakes; i++){
Cake newCake (cakeCost); //If this is the same per cake, I would make this a const
cakes.push_back(newCake);
}
}
每当您创建新的CakePacket
时,这都会将矢量添加到矢量中。只是不要忘记告诉你的构造函数要制作多少个蛋糕。
答案 2 :(得分:-1)
创建A类对象,
1)在堆栈中,
A a
2)在堆中,
A* pa = new A
如果构造函数中有参数,例如A(int x, int y)
,请添加参数
A a(1, 2)
或
A* pa = new A(1, 2)
当堆栈中的对象超出其定义的范围时,它将自动删除。但是堆中的对象需要手动删除。
delete pa
。
因此,要创建4个蛋糕对象,需要将参数传递给对象,例如
std::vector<Cake*> vec;
for (int i = 0; i < 4; ++i) {
vec[i] = new Cake(i);
}
答案 3 :(得分:-1)
要将对象添加到CakePacket类,您必须对其进行修改:
class CakePacket
{
private:
Cake *cArr[4];
public:
CakePacket() //there have to be 4 Cake objects in CakePacket
{
cArr[0] = cArr[1] = cArr[2] = cArr[3] = NULL;
}
~CakePacket() {
for(int i=0; i<4; i++) {
if(cArr[i]) {
delete cArr[i];
cArr[i] = NULL;
}
}
}
bool addCake(Cake *c) {
for(int i=0; i<4; i++) {
if(!cArr[i]) {
cArr[i] = c;
return true;
}
}
return false;
}
};
更好的解决方案是使用容器类(如std::vector
)而不是数组。
现在,您可以通过调用add方法添加蛋糕:
CakePacket p();
p.addCake(new AppleCake(1,2));
p.addCake(new Cake(4));