2013-07-31 79 views
0

從Java/C#背景的虛擬繼承,需要一點幫助瞭解正在發生的事情在這裏C++ ...C++從非成員函數

class A { 
    int x; 
    public: 
    A(int x) : x(x){} 

    void f(int y) { 
    cout << x + y << endl; 
    } 
}; 

class B : virtual A { 
    int x; 
    public: 
    B(int x) : A(2*x), x(x) {} 
    virtual void f(int y){ 
     cout << x + 2*y << endl; 
    } 
}; 

void h(){ 
    B b(5); 
    A &a = dynamic_cast<A &>(b); 
    a.f(10); 
    b.f 
} 

void g() { 
    A *a = this; 
    a->f(10); 
    B *b = dynamic_cast<B *>(a); 
    b->f(10); 
} 

調用H()是確定的,但調用g()將不起作用。有人能解釋爲什麼嗎?此外,在行A(int x):x(x){}什麼:x(x){}呢?對於B(int x)同樣的問題:A(2 * x),x(x)和:A(2 * x),x(x)。

非常感謝您的幫助。

+0

你不能在非成員函數中使用'this'。你的'dynamic_cast'將失敗,因爲'a'不指向'B'對象。 – juanchopanza

+2

你期望''this'在'g()'中引用了什麼?至於你的第二個問題,那個構造被稱爲「成員初始化列表」,並且在構造對象成員時用於提供參數。 – Mankarse

+4

你真的需要解決這個問題。建立一個小的,可編輯的例子,練習你的關注,然後問。 –

回答

2

A(INT X):X(X){}什麼呢:X(X){}做?

: x(x)是初始值設定項列表。 palenthesis中的變量是接收到的參數,而外部變量是成員變量。這意味着成員變量x用接收到的參數值x初始化。

B(INT X):A(2 * X)

在這裏,你呼叫的基類的構造(即,A),其接收一個整數。 x是構造函數B收到的變量。這是從派生類構造函數調用參數化基類構造函數的一種方法。默認情況下,派生類構造函數調用默認的基類構造函數。在你的情況下,如果你沒有提供A(2*x)它會失敗,因爲基類沒有默認的構造函數。

+0

感謝您的回覆。我的印象是編譯器會生成一個默認的構造函數,如果沒有提供?在這種情況下這不是真的嗎? [來源](https://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Fcplr376.htm) –

+1

如果你**創建一個自定義構造函數**,編譯器**不會生成**默認構造函數。 –

0

g是文件範圍的函數,也就是說它不屬於任何類。因此,您不能使用this

: x(x) -style表達式是成員構造函數 - 它們初始化(即調用構造函數)類的成員。

1

g()只是一個免費的功能,不是一個類的成員,所以this沒有意義。我不完全相信你想在那裏做

至於什麼:

A(int x): x(x) 

A類有int x作爲成員。這將調用該整數的構造函數,並將值x傳遞給構造函數A。在我看來,這是不好的風格,你應該區分兩者。例如

class A { 
    int x; 
    public: 
    A(int x_in) : x(x_in){} 

    //... 
}; 

這相當於

class A { 
     int x; 
     public: 
     A(int x_in) { 
      x = x_in; 
     } 
     //... 
    }; 
+0

是的,我意識到這沒有意義。我沒有寫這個,這是一個考試的問題。我認爲一個可憐的人。所以:A(2 * x),x(x)會調用A的x和B的x?仍然對此感到困惑。 –

+0

'A :: x'將是2 * x **(傳遞的x)**,'B :: x'將是傳遞的x的值。 –

1

1)根據MSDN(回覆您的問題與g()相關);

指針是僅在一個類,結構,或聯合類型的非靜態成員函數的指針訪問。它指向調用成員函數的對象。靜態成員函數沒有這個指針。

2)A(int y) : x(y) {}初始化A::x()與內部的值之前該成員的"()"y(修飾的可變名稱以便更好地理解)。同樣是這樣,與B(int x) : A(2*x), x(x) {}。它調用基類的( A)構造與參數然後初始化B::x()內的值,即x

3)鋁所以,g()將無法​​正常工作,因爲dynamic_cast<>會引發編譯錯誤,因爲正在傳輸的對象需要至少有1個虛函數。如果唯一的虛函數是析構函數,那麼dynamic_cast<>就可以工作。

+0

好的,所以任何虛擬成員函數都會使A變形?這與純粹的虛擬方法不同,它會使所有的A虛擬?是對的嗎?謝謝,第一次使用C++。 –

+0

在'A'中有一個純虛擬成員方法(我假設你的意思是「成員」)將有助於「(因爲它是虛擬的),但是你不能實例化任何'A'類型的對象**,因爲那純粹的虛擬功能。 –

+0

也許這將有助於http://stackoverflow.com/questions/1306778/c-virtual-pure-virtual-explained –