c++ - 可以把这个传给会员吗?
问题描述
我有一堂课Data
。该类包含 2 个(或更多)类实例OtherData
。现在,OtherData
(作为成员存储在 class 中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
对象(例如按值作为参数传递)对象,您就会遇到混乱。
Data
选项 A:禁用对象的复制和移动
处理此问题的一种方法是禁用复制和移动。一旦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; }
推荐阅读
- javascript - 如何解决 UnhandledPromiseRejectionWarning?
- python - 如何将 shellcode 转换为原始字节?(Python)
- python - ModuleNotFoundError:没有名为“html.parser”的模块
- excel - 如何在工作表 1 上选择文本框?
- amqp - 如何为 Qpid C++ Broker 1.39.0 同时启用 AMQP 1.0 和 AMQP 0-10
- firebase - Firebase 存储规则,Libre Office contentTypes
- java - 为什么使用spring jpa在postgres中找不到关系错误?
- c# - 无法从终端或管道运行 .net Framework Nunit 项目
- c# - Error: Each parameter in constructor must bind to an object property or field on deserialization
- typescript - 在使用 MS Bot 框架 V4 的 MS 团队聊天机器人中按下英雄卡上的任何按钮后会发出成功通知