可选参考成员 - 是否可能?

jac*_*hab 2 c++ class constructor-overloading

我有以下课程

class CItem
{
    public:
        CItem(CRegistry &Registry) _Registry(Registry) {Registry.Register();}
        ~CItem() {_Registry.Unregister()};


    private:
        CRegistry &_Registry;
}
Run Code Online (Sandbox Code Playgroud)

经过一段时间后,事实证明并非所有CItem对象都需要注册,因此我需要一个CItem版本,它不需要构造函数中的Registry(当然还有注册代码).我该如何实现呢?我在这里看到的唯一解决方案是获取并保持Registry作为指针.是否有更优雅的解决方案,如使用模板等(我不喜欢从引用切换到指针)?

Dav*_*eas 8

如果要保留单个类,只需将属性更改为原始指针并允许它为null.正如尼尔所指出的那样,对于原始指针存在广泛的不合理的圣战,这种说法并不完全合理.使用原始指针并清楚地记录(注释)该对象不拥有指向内存的所有权,这样就不会有人想delete在以后的析构函数中添加一个.

所有其他解决方案都比在内部使用指针更糟糕.这是一个实现细节.还要考虑它是否有意义.您的代码将无法再认为指针有效,并且会使您的类中的逻辑复杂化.

class CItem
{
public:
   CItem(CRegistry &Registry) : _Registry(&Registry) {Registry->Register();}
   CItem() : _Registry(0) {}
   ~CItem() { if ( _Registry ) _Registry->Unregister(); }

private:
   CRegistry *_Registry; // Pointer is not owned. Do not delete!
};
Run Code Online (Sandbox Code Playgroud)

作为最后一点:不要为属性添加单个下划线,因为它们是由C++实现的标准(编译器和标准库)保留的


小智 5

唯一的另一种选择是创建一个CItem基类,然后从中派生ItemWithRef(有一个引用)和ItemWithoutRef.但是使用指针会更容易和更清晰.

从关于作为成员的引用的问题的数量,似乎在某个地方,有人正在传播引用是好的指针和指针是坏的.事实并非如此,特别是涉及数据成员时.

只是为了澄清下划线的事情:

  • 以下划线和低位字母开头的名称是在C++编译/库编写器出现在命名空间(即类外)范围时保留的

  • 名称以下划线和大写字母开头,或包含两个连续的下划线,无条件保留给编译器/库编写者 - 您不能在自己的代码中使用它们