1

你能帮我用 C++ 编写作文示例应用程序吗?

我需要这样的层次结构:AppleCake 类继承自基类 Cake,并且有 CakePacket 类,它有 4 个 Cakes。我编写了部分代码,但问题是我不知道如何将 4 个 Cake 对象添加到 CakePacket。我是 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 对象添加到其他类不会有问题。

谢谢大家的回答!

4

4 回答 4

7

因为在最后一个小时没有人做对了......实际上@taylorc93 是最接近的,但他仍然犯了一个错误。

所以,回到问题。CakePacket 应该是用来存放蛋糕的,对吧?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) };

如果您希望能够从类似数组的列表中创建,您需要提供额外的构造函数 take initializer_list<Cake>,但我将把它留作练习。(提示:你不需要循环for

CakePacket 真的有必要吗?

这是一个学习问题,所以我不会对它挑剔,但我想指出 CakePacket 是如何真正做到的……没有什么,至少在目前的状态下是这样。有时简单地使用std容器会更容易,而不是将其包装在一个全新的类型中。这避免了用多余的类污染代码,并且您会惊讶于标准库为您提供了多少功能来使用它的容器。

警告

如果您尝试将 AppleCake 存储在其中,diameter则会被切片,即仅保存公共部分。在这种情况下,您需要存储指向基类的指针(使用boost::ptr_vector<Cake>or std::vector<std::unique_ptr<Cake>>),或者使用类似Boost.Variant.

你肯定不想在这里做的事

...正在存储原始指针。您必须销毁在 CakePacket dtor 中添加的每个 Cake,这很容易出错并且根本没有必要。

使用 C 风格的数组也很糟糕,因为它会限制您使用固定大小。

于 2013-07-08T14:19:26.770 回答
0

好的,这不是太难解决。首先,我建议使用std::vector而不是任何数组。如果您不知道向量是什么,您可以将它们视为没有限制的数组(也就是您无需担心是否需要扩展它以添加更多内容)。你可以像这样声明一个向量:

std::vector<the type of each object in the vector> someName

其次,这可能是一个错字,但看起来你的AppleCake类继承自Brake, not Cake,所以如果这是一个错字,你应该修复它。

现在,要将 4 个蛋糕添加到您CakePacketCakePacket. 然后,您可以像这样将它们添加到蛋糕中:

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. 只是不要忘记告诉您的构造函数要制作多少个蛋糕。

于 2013-07-08T13:32:02.700 回答
-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);
    }
于 2013-07-08T12:58:30.243 回答
-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));
于 2013-07-08T13:04:25.570 回答