通过引用或指针来共享对象 [英] Sharing object by reference or pointer

查看:191
本文介绍了通过引用或指针来共享对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  class A 
{
public:
bool初始化(B ?? b);
private:
B? m_B;
}

对象B必须存在。因此,我认为通过引用传递它,而不是通过指针传递并且在B是NULL的情况下失败Initialize()。



m_B的唯一的属性是类型的指针B(它不能是B的引用,因为B的初始化不在A中)。因此Initialize应该是这样:

  bool A :: Initialize(B& b)
{
m_B =& b;
....
}

这个aproach是否确定? p>

UPD:


  1. 不是新的,我只是试图修复一些问题。
    其实我不是说一些具体的A和B类,而是我的代码库中遇到的问题。


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


  3. shared_ptr可以是NULL ,所以传递给A :: Initialize()不同于传递指针到B,在这方面,Initialize()的签名不声明B是否是​​强制的。在我的例子中,它是,我想通过引用B来表示。


  4. 我们的代码目前没有使用boost。所以,虽然shared_ptr比只是传递raw指针更好的解决方案,但是我提出的解决方案可以认为是坏的,但仍然是解决方案。



解决方案

我会留在指针。
此处的引用仅发送错误消息。



在计划将指针指向对象
的情况下,不要使用对象的引用或共享它等。
在C ++中引用的主要原因是允许类似操作符重载
和复制构造函数来为用户定义类型工作。
如果没有它们,将很难用语法
提供与内置类型没有区别的功能。



但在这种情况下不要试图模仿内置类型。
你正在通过指针操作通常使用的对象,
甚至通过几个不同的指针共享。



对于 b 为NULL ,通过使用 assert(b)(或类似的结构)
强制执行合同并停止无效程序。
(我不会抛出异常。
即使你忘记了C ++中的异常问题,
是你计划在你的代码中捕获和处理这样的异常吗?)
我还将添加这样的断言到所有使用 m_B
的代码,以防有人忘记调用 A :: Initialize()



使用引用来确保指针不为null,可能会失败。
在大多数实现中,您可以从NULL或悬挂指针
引用,而不会引发任何错误。
只有当您尝试使用此引用时,您的应用程序才会失败。
因此,如果有人不小心通过你 B * pb 这等于NULL,
你可以调用 pa-> pb),没有任何反应。
除了 pa-> m_B 现在为NULL。



是否使用 boost :: shared_ptr 取决于你和你的记忆策略
管理。
这是一个完全不相关的问题。


Say I have an object of type A having Initialize() method. The method receives object B, which are kept as the object data member. B object is shared between several objects, thus A should contain the originally received B object and not its copy.

   class A 
   {
       public:
          bool Initialize(B?? b);
       private:
          B?? m_B;    
    }

Object B must present. Thus I think to pass it by reference, instead of passing by pointer and failing Initialize() in case B is NULL.

The only alrernative for m_B is to be of type of pointer B (it cann't be reference of B, since the intializating of B is not done in A c-tor). Thus Initialize should look like:

bool A::Initialize(B& b) 
{
    m_B = &b;
    ....
}

Is this aproach is ok?

UPD:

  1. The code is not new and I'm just trying to "fix" some problems. Actually I'm not talking about some concrete A and b classes, rather about a way the problem is approached in my code base. The code widely passes pointer to B and verifying it in Initialize() if it's NULL.

  2. Passing B to A's c-tor is not always a good option too. There're also other parametrs passed to A, which are not exists at A creation time. Therefore I woudln't prefer to pass part of parameters to A c-tor and the rest to A::Initialize().

  3. shared_ptr can be "NULL" too, so passing it to A::Initialize() not different from passing just pointer to B, in that aspect that signature of Initialize() dosn't declare if B is mandatory or not. In my case it is and I want to express it by passing reference to B.

  4. Our code currently is not using boost at all. So, although shared_ptr better solution than just passing raw pointer, can solution proposed by me be considered as bad, but still solution.

解决方案

I'd stay with pointer. Reference here just sends wrong message.

You don't use references to object in situations when you plan to take pointer to object and keep or share it, etc. Main reason for references in C++ is allowing things like operator overloading and copy constructors to work for user defined types. Without them it would be difficult to provide this functionality with syntax that doesn't differ from built in types.

But in this situation you're not trying to mimic built in type. You are operating on object which is normally used through pointer and even shared through several different pointers. So be explicit about that.

As for b being NULL, by all means use assert(b) (or similar construct) to enforce contract and stop invalid program. (I wouldn't throw exception though. Even if you forget about problems with exceptions in C++, are you planning to ever catch and handle such exception in your code?) I would also add such assertions to all code that uses m_B in case someone forgot to call A::Initialize().

Using reference to ensure pointer is not null, might misfire. In most implementation you can make reference from NULL or dangling pointer without raising any error. Your application will fail only if you try to use this reference. So if someone accidentally passes you B *pb which equals NULL, you could call pa->Initialize(*pb) and nothing happens. Except that pa->m_B is now NULL.

Whether to use something like boost::shared_ptr is up to you and your strategy of memory management. It's a completely unrelated issue.

这篇关于通过引用或指针来共享对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆