您可以从抽象引用创建具体对象的副本

时间:2013-10-02 21:44:52

标签: c++

我有一组类:Value,ReportItem,ReportMessage。 Value类是抽象的,具有许多不同的具体实现(例如IntValue,FloatValue,DoubleValue等)。通过传递对值的引用来创建具体类时,将具体类添加到ReportItem:

ReportItem(Value& value);

然后使用“addItem”方法将ReportItems添加到ReportMessage中,该方法获取报告项的副本并将其松散:

class ReportMessage {
    ...
    void addItem(ReportItem item);
}

因此,代码段可能如下所示:

IntValue value(1);
ReportItem item(value);

ReportMessage message;
message.addItem(item);

创建ReportItem的副本我没有问题,但我对Value有问题,因为它是一个抽象类。创建ReportItem时,它会引用Value对象并保留该引用,直到删除ReportItem。这是一个问题,因为如果在ReportItem完成之前删除了Value对象,地球将从轴上脱落并旋转到太阳中。

有没有一个好方法来处理这个问题?我想要的是一种方法来引用Value对象(Value&)并以某种方式创建具体对象的副本,然后由报表项保留。这是可能的,还是有更好的方法。

感谢。

注意:我没有使用C ++ 11。

1 个答案:

答案 0 :(得分:1)

作为简化示例,以下是如何使ReportItem类拥有该值的方法。你需要努力学习复制和赋值语义(“虚拟拷贝构造函数”等),但我留给你解决(即搜索这个站点上的现有答案):

class ReportItem
{
    Value * vptr;    // vptr is the first thing in the class
public:
    ReportItem(int n) : vptr(new IntValue(n)) { }
    ReportItem(float x) : vptr(new FloatValue(x)) { }
    ~ReportItem() { delete vptr; }

    // write difficult copy and assignment logic!
};

没有C ++ 11会让它变得比它需要的更麻烦,因为你没有合理的移动语义,可能需要制作大量不必要的副本。

(在C ++ 11中,你只有一个std::unique_ptr<Value>成员,没有明确的析构函数,你可以说message.addItem(ReportItem(1.5));。)