可以将其传递给成员吗?

时间:2019-08-07 23:58:47

标签: c++

我有一个Data班。该类包含2个(或更多)类OtherData的实例。现在,OtherData的每个实例(作为成员存储在类Data中)具有一些共同的数据。我不希望OtherData的每个实例都拥有它们共有的那个数据的副本。例如,OtherData可以共享CommonData类型的对象。

现在,我决定将公用数据存储在Data类中。在构造时,OtherData的实例将接收到指向Data实例的指针,以便能够访问公用数据。我决定采用这种方式来避免实现类CommonData。看起来更简单,更短。

一个简短的例子:

// the class which contains the common data as well as the instances of OtherData
struct Data;

struct OtherData
{
    OtherData(const Data* data) : _data { data } {}
    const Data* _data;
    int getCommonData() const;
};

struct Data
{
    Data() : _data1 { this }, _data2 { this } {}
    Data(const Data&) = delete;
    Data(Data&&) = delete;
    Data& operator=(const Data&) = delete;
    Data& operator=(Data&&) = delete;
    OtherData _data1, _data2;
    int getData() const { return 1; }
};

int OtherData::getCommonData() const  { return _data->getData(); }

现在,从OtherData的实例中,我可以轻松获得公用数据。

我通常避免将this传递给成员,我讨厌循环依赖(这意味着一个对象包含另一个对象,而后者具有对前者的引用或指针)。但是,这似乎很简单,我无法证明这是一个糟糕的设计。

所以,我的问题是:您会避免这种设计吗?为什么?还是您认为可以接受?

1 个答案:

答案 0 :(得分:0)

这是一个脆弱的设计。复制或移动最初的Data对象(例如,按值作为参数传递),您会感到混乱。

选项A:禁止复制和移动Data个对象

处理此问题的一种方法是仅禁用复制和移动。创建Data对象后,就无法复制或移动该对象,从而确保OtherData中的指针保持有效。这是一种快速的解决方案,但是非常严格,但是在某些非常特定的情况下可以接受。

struct Data
{
     Data() { /* .. */ }

     Data(const Data&) = delete;
     Data(Data&&) = delete;
     Data& operator=(const Data&) = delete;
     Data& operator=(Data&&) = delete;
};

选项B:使用智能指针

每当您处理需要从多个对象访问的资源时,请考虑实现RAII的智能指针。现在,您必须在unique_ptrshared_ptr之间进行选择。如果CommonData的生存时间应与Data个对象一样长(没有OtherData个生存期为Data),则可以使用unique_ptr,否则需要{{1} }。

使用shared_ptr的示例:

unique_ptr