![](/img/trans.png)
[英]Question of using static_cast on “this” pointer in a derived object to base class
[英]static_cast derived this object to base class in C++
在閱讀 Item 27 Minimize cast in Effective C++<\/strong>時,它說不要嘗試使用
static_cast<\/code>將派生類中的
*this<\/code>強制轉換為基類。
這是因為
static_cast<Base>(*this)<\/code>會創建一個 Base class 的臨時對象<\/strong>。
我嘗試了一個如下示例,但是,它始終使用不同的編譯器輸出 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;
}
一個更有意義的例子是這個:
#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(); }
};
無論如何,您面臨的問題稱為slicing 。
這就是為什么如果您不知道自己在做什么,不鼓勵使用static_cast<A>(*this)
的原因。
請參閱此處了解更多詳情。
您的代碼的問題是您沒有修改
A<\/code>變量
a<\/code>值,因此您看不到兩個實例的值之間的變化。
為
A<\/code>添加以下復制構造函數:
A() = default; // so that it still exists...
A(A const& other)
: a(other.a + 1) // initialise to a value definitely differing...
{ }
首先,您不必強制轉換 Derived -> Base,因為它會自動發生。 是的, 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
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.