在阅读有效C ++ 中的第27项最小化强制转换时,它表示不要尝试使用static_cast
将派生类中的*this
强制转换为基类。这是因为 static_cast<Base>(*this)
将创建一个Base类的临时对象。我尝试了如下示例,但是,它总是使用不同的编译器输出10,例如clang 3.8和gcc 4.9,5.3。
我错了吗?
#include <iostream>
class A {
public:
int a;
virtual void foo() {std::cout << a << std::endl;}
};
class B : public A {
public:
int b;
void foo () { static_cast<A>(*this).foo();}
};
int main () {
B b;
b.a = 10;
b.foo();
return 0;
}
问题是为什么static_cast
会创建一个临时对象。
答案 0 :(得分:2)
一个更有意义的例子就是这个:
#include <iostream>
class A {
public:
virtual void foo() { std::cout << "A" << std::endl; }
};
class B : public A {
public:
virtual void foo() { std::cout << "B" << std::endl; }
void bar () { static_cast<A>(*this).foo(); }
};
int main () {
B b;
b.bar();
}
我希望bar
打印B
,因为foo
是一种重写方法。它会打印A
嗯,从语言的角度来看,这是正确的,从开发人员的角度来看,这种情况并没有那么好,期待完全不同的结果。
如果您使用以下类,则可以使用它:
class B : public A {
public:
virtual void foo() { std::cout << "B" << std::endl; }
void bar () { static_cast<A*>(this)->foo(); }
};
另外一个按预期工作(为了清楚起见,在评论中感谢@MORTAL):
class B : public A {
public:
virtual void foo() { std::cout << "B" << std::endl; }
void bar () { static_cast<A&>(*this).foo(); }
};
无论如何,您面临的问题是切片
这就是为什么如果你不知道你在做什么,就不鼓励使用static_cast<A>(*this)
。
有关详细信息,请参阅here。
答案 1 :(得分:-1)
首先,您不必投射衍生 - &gt;基础因为它自动发生。是的,static_cast将创建一个你要转换为的类型的对象。 在您启用多态的情况下,您可以使用引用或指针:
int main(){
B b;
A &a = b; // no explicit cast needed
a.foo(); // will call B::foo
//OR
B *bPtr = new B;
A *aPtr = bPtr; // no explicit cast needed
aPtr->foo(); // same as above
}