C++ 转换操作符正在切片我的对象
我从以下代码中获得意外行为:C++ 转换操作符正在切片我的对象,c++,object-slicing,conversion-operator,C++,Object Slicing,Conversion Operator,我从以下代码中获得意外行为: struct Base { Base() {} virtual ~Base() {} virtual void foo() const = 0; protected: Base(const Base &) {} }; struct Derived : public Base { Derived() {} Derived(const Derived &other) : Base(other) {}
struct Base
{
Base() {}
virtual ~Base() {}
virtual void foo() const = 0;
protected:
Base(const Base &) {}
};
struct Derived : public Base
{
Derived() {}
Derived(const Derived &other) : Base(other) {}
virtual void foo() const {}
};
struct NewDerived
{
operator const Derived() { return Derived(); }
};
void func(const Base &b)
{
b.foo();
}
int main()
{
func(NewDerived());
return 0;
}
在MSVC2008中,我在main()中遇到以下编译错误:
为什么它试图访问Base的复制构造函数
如果我将Base的复制构造函数设置为公共的,那么代码会在运行时编译并分割返回值,并且在func()中调用foo()会触发一个名为error的纯虚拟函数
有人能解释一下吗?标准中的相关引用在8.5.3p5(C++11)中: 具有类类型(即T2是类类型),其中T1不是 与T2相关的引用,并且可以隐式转换为xvalue, prvalue类,或“cv3 T3”类型的函数左值,其中“cv1 T1”为 与“cv3 T3”兼容的引用,则该引用绑定到 初始值设定项表达式的值(在第一种情况下)和 第二种情况下的转换结果(或在任何一种情况下,转换为 适当的基类子对象) 例如: 在您的情况下,
T1
是Base
,T2
是NewDerived
,T3
是Derived
。从上面的引用中,不应调用复制构造函数,并且左值引用应绑定到Base
子对象
但是,请注意,在C++03中,情况并非如此。在C++03中,以下引用是相关的:
如果初始值设定项表达式为右值,T2为类类型,并且
“cv1 T1”是与“cv2 T2”兼容的引用,引用是绑定的
到由右值表示的对象(请参见3.10[basic.lval]),或到
该对象中的子对象
否则,将创建并初始化“cv1 T1”类型的临时文件
使用非引用的规则从初始值设定项表达式
复制初始化(8.5[dcl.init])。然后将引用绑定到
临时的
引用的第一段不适用,因为
Base
与NewDerived
的引用不兼容,因此只有最后一段适用,这意味着必须创建临时Base
对象。因此,MSVC2008和gcc符合C++03规则。作为旁注,为什么对代码的以下细微更改允许它进行编译,至少在VS中是这样:int main(){const Base&b(NewDerived();}
有什么想法吗???@AlexK:你被打动了。尝试const Base&b((NewDerived())代码>(注意额外的括号)。@Jesse明白了。太棒了!谢谢大家。那很有帮助。如果你有任何创造性的想法,我会加上一个额外的问题。@kede:很难用一小段代码就说出来。我不明白为什么转换函数不返回文件
?也许单独问一个完整代码的问题会有所帮助。
error C2248: 'Base::Base' : cannot access protected member declared in class 'Base'
struct A { };
struct B : A { } b;
extern B f();
const A& rca2 = f(); // bound to the A subobject of the B rvalue.
A&& rra = f(); // same as above
struct X {
operator B();
operator int&();
} x;
const A& r = x; // bound to the A subobject of the result of the conversion