参考成员必须是Const?

时间:2010-09-03 16:36:44

标签: c++ constructor initialization const

在这个简单的例子中,为什么我需要创建'member'const以便编译它?

struct ClassA
{
    ClassA(int integer) {}
};

struct ClassB
{
    ClassB(int integer):
        member(integer)
    {
    }

    const ClassA& member;
};

int main()
{
    ClassB* b = new ClassB(12);

    return 0;
}

否则,我收到此错误:

  

错误:初始化无效   “ClassA&”类型的参考从   'int'类型的表达式

4 个答案:

答案 0 :(得分:10)

原因是这里实际发生的是你在int的初始化中使用从ClassAmember的隐式转换。在扩展形式中,它实际上正在执行以下操作

member(ClassA(integer))

这意味着ClassA实例是临时的。仅引用临时变量const引用是不合法的,因此会出现编译器错误。

最简单的解决方法是删除成员上的&修饰符,并将其设为ClassA

类型
ClassA member;

此外,将explicit置于ClassA构造函数前面以避免静默隐式转换是一种很好的做法。

explicit ClassA(int integer){}

答案 1 :(得分:4)

因为您试图存储对临时对象的引用,并且您只能将常量引用存储到临时对象。

当您尝试使用类型为member的{​​{1}}参数初始化ClassA&类型的integer引用时,隐式转换构造函数int将变为inovked从ClassA::ClassA(int integer)变量生成ClassA类型的未命名临时对象。然后使用该未命名的临时对象初始化引用integer,创建一个临时引用,该引用必须是const。

我在这里质疑你的设计。如果您尝试使用按值传递给member构造函数的数据初始化member,那么将ClassB作为参考可能不是正确的做法。为什么你认为member应该是一个参考而不仅仅是一个对象?

答案 2 :(得分:0)

ClassA是ClassB的引用成员,因此必须使用ClassA实例进行实例化。

答案 3 :(得分:0)

您正在创建一个临时的,并初始化该临时的引用。就像通常一样,要绑定到临时,引用必须是const。

我对此有一些认真的想法。具有引用成员的类很少有用。当它很有用时,您通常希望从一些现有对象开始,并将对该对象的引用传递给成员引用。执行此操作时,需要以确保引用的对象在包含引用的对象的整个生命周期中都存在,因此这两个完全紧密耦合 - 您通常宁愿避免。