簡體   English   中英

"static_cast 將此對象派生到 C++ 中的基類"

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM