在这个简单的例子中,为什么我需要创建'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'类型的表达式
答案 0 :(得分:10)
原因是这里实际发生的是你在int
的初始化中使用从ClassA
到member
的隐式转换。在扩展形式中,它实际上正在执行以下操作
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。
我对此有一些认真的想法。具有引用成员的类很少有用。当它很有用时,您通常希望从一些现有对象开始,并将对该对象的引用传递给成员引用。执行此操作时,需要以确保引用的对象在包含引用的对象的整个生命周期中都存在,因此这两个完全紧密耦合 - 您通常宁愿避免。