C++ 通过引用或指针共享对象

C++ 通过引用或指针共享对象,c++,C++,假设我有一个具有Initialize()方法的类型为A的对象。 该方法接收对象B,对象B作为对象数据成员保存。 B对象在多个对象之间共享,因此A应该包含最初接收的B对象,而不是其副本 class A { public: bool Initialize(B?? b); private: B?? m_B; } 对象B必须存在。因此,我认为应该通过引用来传递它,而不是在B为NULL的情况下通过指针传递并

假设我有一个具有Initialize()方法的类型为A的对象。 该方法接收对象B,对象B作为对象数据成员保存。 B对象在多个对象之间共享,因此A应该包含最初接收的B对象,而不是其副本

   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:

  • 代码不是新的,我只是想“修复”一些问题。 实际上,我不是在谈论一些具体的A和b类,而是在我的代码库中处理这个问题的方法。代码广泛地将指针传递到B,并在Initialize()中验证它是否为NULL

  • 把B传给A的c-tor也不总是一个好的选择。还有其他传递给的参数,它们在创建时不存在。因此,我不希望将部分参数传递给c-tor,将其余参数传递给A::Initialize()

  • shared_ptr也可以是“NULL”,因此将其传递给A::Initialize()与只传递指向B的指针没有什么不同,在这方面Initialize()的签名不会声明B是否是必需的。在我的例子中,它是,我想通过传递对B的引用来表达它

  • 我们的代码目前根本没有使用boost。所以,虽然shared_ptr解决方案比仅仅传递原始指针更好,但我提出的解决方案可以被认为是坏的,但仍然是解决方案


  • 我会选择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);
        }
    };