可以将其传递给会员吗?

Is it ok to pass this to member?

本文关键字:      更新时间:2023-10-16

我有一个类Data.该类包含类OtherData的 2 个(或更多(实例。现在,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传递给成员,我讨厌循环依赖(我的意思是包含另一个对象的对象,而后者具有指向前者的引用或指针(。然而,这似乎很容易,我未能证明这是一个糟糕的设计。

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

这是一个脆弱的设计。复制或移动初始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,否则您需要shared_ptr

使用unique_ptr的示例:

#include <memory>
struct CommonData
{
int a;
CommonData(int a) : a{a} {}
};
struct Data;
struct OtherData
{
OtherData(const CommonData* common_data) : _common_data { common_data } {}
const CommonData* _common_data;
int getCommonData() const;
};
struct Data
{
Data()
: _common_data{std::make_unique<CommonData>(1) },
_data1 { _common_data.get() },
_data2 {  _common_data.get() }
{}
// this field must be declared before any `OtherData` fields
std::unique_ptr<CommonData> _common_data;
OtherData _data1, _data2;
};
int OtherData::getCommonData() const  { return _common_data->a; }
相关文章:
  • 没有找到相关文章