可以将其传递给会员吗?
Is it ok to pass this to member?
我有一个类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_ptr
和shared_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; }
- 没有找到相关文章