我需要以下代码才能工作:
class Parent{
public:
virtual void fun(){throw 0};
};
class Child:public Parent{
public:
virtual void fun(){/*Success*/};
};
Parent& getChild(){
return *(new Child());
}
void main(){
auto child=getChild();
child.fun();
}
但由于某种原因,auto
创建了Parent
而不是Parent &
,这将正确地使用派生方法。有没有办法强制auto
创建引用,而不是使用简单的实例?
C++标准解释了auto是从initializer值中扣除的:
声明
[dcl.spec.auto]/1:
auto
和decltype(auto)
类型说明符用于指定占位符类型后来被初始化项的推导所取代Initializers
[dcl.init]/1:
声明符可以指定初始值值。
因此,当您编写以下声明符时:
int t = f(10);
auto x = y;
auto child = getChild();
右侧被求值为生成值的表达式。这个值用于初始化左侧声明的变量。
值不是引用。它不像指针和地址。在表达式求值中,无论何时使用引用,都会考虑引用的值。您可以通过以下简单片段看到这一点:
int x=15;
int&y = x;
cout << x <<", " << y <<", " << &x<<endl;
cout << typeid(x).name() <<", " << typeid(y).name() <<", " << typeid(&x).name() <<endl;
因此,在您的情况下,表达式值是Parent
,而不是Parent &
。这就是为什么您的auto
将被推断为具有Parent
类型。
然而,C++标准并没有以相同的方式考虑所有的值。在 xvaluesrvalues当你有这样一个左值时,你可以创建一个对它的引用: 但你需要明确地说,你的汽车应该是一个参考: 编辑:关于汽车工作方式的更多信息:Herb Sutter的GotW博客[basic.lval]
中,它对不同类型的值进行了重要的区分,这些值可以是lvalues、[dcl.ref]
/2:使用&
声明的引用类型称为左值参考,(…(auto &child = getChild();