C++ 通过引用或指针共享对象
假设我有一个具有Initialize()方法的类型为A的对象。 该方法接收对象B,对象B作为对象数据成员保存。 B对象在多个对象之间共享,因此A应该包含最初接收的B对象,而不是其副本C++ 通过引用或指针共享对象,c++,C++,假设我有一个具有Initialize()方法的类型为A的对象。 该方法接收对象B,对象B作为对象数据成员保存。 B对象在多个对象之间共享,因此A应该包含最初接收的B对象,而不是其副本 class A { public: bool Initialize(B?? b); private: B?? m_B; } 对象B必须存在。因此,我认为应该通过引用来传递它,而不是在B为NULL的情况下通过指针传递并
class A
{
public:
bool Initialize(B?? b);
private:
B?? m_B;
}
对象B必须存在。因此,我认为应该通过引用来传递它,而不是在B为NULL的情况下通过指针传递并失败Initialize()
m_B的唯一属性是指针B的类型(它不能是B的引用,因为B的初始化不是在c-tor中完成的)。因此,初始化应该如下所示:
bool A::Initialize(B& b)
{
m_B = &b;
....
}
这样行吗
UPD:
我会选择boost::shared_ptr。如果您使用引用,您可能需要担心引用对象的范围,如果您使用普通指针,您将在内存管理方面遇到麻烦。谁将删除B
也许只是再考虑一下你的方案:你真的需要共享这个对象吗?或者B型的复制就足够了吗?如果B将被其他类更改,并且这些更改需要被其他类知道,那么您需要一个共享的ptr 我要用boost::shared\u ptr。如果您使用引用,您可能需要担心引用对象的范围,如果您使用普通指针,您将在内存管理方面遇到麻烦。谁将删除B
也许只是再考虑一下你的方案:你真的需要共享这个对象吗?或者B型的复制就足够了吗?如果B将被其他类更改,并且这些更改需要被其他类知道,那么您需要一个共享的ptr 如果B是可选的,那么它可以表示为指针。如果需要B,则应将其表示为参考 如果可能,尝试并避免使用初始化方法进行“两阶段施工”。如果不能做到这一点,那么在A内部,您需要将B视为可选的,因此将其存储为指针,并在您可能希望使用它的任何地方进行测试 如果您的初始化方法(或者,理想情况下,构造函数)需要一个B,那么您应该将其作为引用传入 这一切都假设你知道谁真正拥有B;可能B拥有A的实例并使用对自身的引用对其进行初始化,或者可能B的所有者也是拥有A的所有引用B的实例的某个对象
如果A的对象共同拥有B,那么您应该使用类似于boost::shared\u ptr的东西来明确共享所有权;假设B是动态分配的new。如果B是可选的,那么它可以表示为指针。如果需要B,则应将其表示为参考 如果可能,尝试并避免使用初始化方法进行“两阶段施工”。如果不能做到这一点,那么在A内部,您需要将B视为可选的,因此将其存储为指针,并在您可能希望使用它的任何地方进行测试 如果您的初始化方法(或者,理想情况下,构造函数)需要一个B,那么您应该将其作为引用传入 这一切都假设你知道谁真正拥有B;可能B拥有A的实例并使用对自身的引用对其进行初始化,或者可能B的所有者也是拥有A的所有引用B的实例的某个对象 如果A的对象共同拥有B,那么您应该使用类似于boost::shared\u ptr的东西来明确共享所有权;假设B是用new动态分配的。我会使用指针。 这里的引用只是发送了错误的消息 在计划将指针指向对象的情况下,不使用对对象的引用 并保存或共享它等。 C++中引用的主要原因是允许操作符重载 和复制构造函数以用于用户定义的类型。 没有它们,就很难用语法提供此功能 这与内置类型没有区别 但在这种情况下,您不会试图模仿内置类型。 您正在对对象进行操作,该对象通常通过指针和 甚至通过几个不同的指针共享。 所以要明确这一点 至于
b
为空,请务必使用assert(b)
(或类似构造)
执行合同并停止无效程序。
(不过我不会抛出异常。
即使你忘记了C++中的异常问题,
您是否计划在代码中捕获并处理此类异常?)
我还将向所有使用mub
万一有人忘记调用A::Initialize()
使用引用来确保指针不为空,可能会导致失火。
在大多数实现中,可以从NULL或悬空指针进行引用
没有引起任何错误。
只有尝试使用此引用时,应用程序才会失败。
因此,如果有人意外地通过了你的B*pb
,它等于NULL,
您可以调用pa->Initialize(*pb)
,但什么也不会发生。
除了pa->mub
现在为空<
class IsEmpty{};
class A
{
B *b_;
int *c_;
char *d_;
void Initialize(B *b)
{
b_ = b;
c_ = b_->Getc();
d_ = b_->Getd();
}
public:
A(B *b)
: b_(0), c_(0), d_(0)
{
if(b == 0) throw IsEmpty();
Initialize(b);
}
};