通过new()调用初始化引用成员

时间:2019-02-28 15:30:13

标签: c++

这样的初始化非常不好吗?

class A
{
public:
    ~A();
    A();

    B &b;
};

A::~A()
{
    delete &b;
}

A::A() :
     b(*(new B()))
{
}

我想要的是访问没有“->”运算符的成员“ b”。同样,我不能使B类成为A类的一部分,因为B类在A类的标题中不完整。

更新:谢谢您的回答!如果您需要更多信息,则此处的类B表示“信号”(回调列表)。在99%的情况下,此类仅是其他类的成员(而不是指针或引用)。但是一个特定的类(在我的示例中为A)不能包含B类头。我仍然希望将A类中的该信号连接起来并像其他任何信号一样调用:

object->signal.connect(...);
object->signal();

带点而不是“->”。 A类不能包含B类头,因为有些模板类继承了A类...

2 个答案:

答案 0 :(得分:7)

拥有引用成员会破坏赋值运算符的语义:与指针不同,它不会重置引用。它还破坏了移动构造函数和赋值。并且无法获得参考成员的sizeof或地址。

我认为,不应使用参考成员,因为它们不会增加任何价值,而只会引入限制。

Bjarne Stroustrup在“ C ++的设计和演变”中解释说,这些引用已引入C ++中,以允许运算符重载和有效的参数传递。这就是引用不能为空(引用表达式操作数或调用参数)并且具有所有这些特殊的非值类型语义的原因。使用参考成员的人正在将参考应用于并非旨在解决的问题。

使用分配的new表达式初始化引用会导致内存泄漏,因为引用(伪)析构函数不会执行任何操作(不会为您调用delete)。

答案 1 :(得分:0)

“这样的初始化非常不好吗?” -不,这不是非常不好。这有点不寻常,不是惯用的,可能会引起很多注意。我会说,这是中等程度的错误,并且似乎没有必要,至少在提供了相关信息的情况下。