你可以用C ++帮我构建组合示例应用程序吗?

时间:2013-07-08 12:46:51

标签: c++ composition

你能帮我用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对象添加到其他类中是没有问题的。

感谢您的所有答案!

4 个答案:

答案 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真的有必要吗?

这是一个学习问题,所以我不会对它挑剔,但我想指出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));