2014-10-20 74 views
2
class A{ 
    int var; 
public: 
    virtual void foo(); // sets var 
    void bar(); // reads var and displays value 
}; 

class B : public A{ 
    int var; 
public: 
    void foo(); 
}; 

void A::bar(){ 
    printf("%d",var); 
} 

void B::foo(){ 
    var = 42; 
} 

void func(){ 
    B myObj; 
    myObj.foo(); 
    myObj.bar(); 
} 

class A2{ 
    virtual void foo(); // sets var 
public: 
    int var; 
    void bar(); // read var and displays value 
}; 

class B2 : public A2{ 
public: 
    void foo(); 
}; 
  1. 當在funcfoo通話將FOO設置A::varB::var
  2. 並致電barfuncbar改爲A::varB::var
  3. 如果不會創建A的實例,是否需要在A中聲明var作爲數據成員?
  4. 請問類聲明A2B2的工作效果與AB相同嗎?
+1

您是否嘗試過簡單地運行代碼以找出答案?在我看來,如果你可以運行並嘗試這個? – MrHug 2014-10-20 14:07:00

+0

我想了解爲什麼有些事情可行,爲什麼不行。當然,我也會運行它。 – tMJ 2014-10-20 14:08:39

+0

'func'不會編譯:'myObj.foo'是私有的。 – aschepler 2014-10-20 14:10:22

回答

2

關於1和2,因爲foo是不可見有一個錯誤(和A::foo還沒有一個機構):

class B : public A{ 
    int var; 
    void foo(); 
}; 

無論如何,因爲你不通過指針/引用調用它

void func(){ 
    B myObj; 
    myObj.foo(); // No polymorphic behavior here, B::foo is called 
    myObj.bar(); // the same, but A::bar is called since B hasn't one 
} 

關於3.和4。如果基類和派生類都有一個具有相同名稱的變量,則派生類將隱藏基類的名稱,並且通過派生對象的每次訪問都將導致派生類被設置/調用(除非明確執行base::var)。如果只有一個擁有它,那就沒問題,他們都會調用相同的版本(只要它是可見/可訪問的)。在你上面的例子:

void A::bar(){ 
    std::cout << var; // This will output an uninitialized A::var! 
} 

void B::foo(){ 
    var = 42; // B's var hides A's var so this only sets the derived one's 
} 

編輯:爲A2B2的情況下還有的A2::var只有一個實例,每個訪問它,甚至從一個派生類中,將參考基地之一,例如

class A2{ 
    virtual void foo() = 0; 
public: 
    int var; 
    void bar() { 
     std::cout << var; // Will correctly output 42 
    } 
}; 

class B2 : public A2{ 
public: 
    void foo() { 
     var = 42; // Sets the common A2::var variable 
    }; 
}; 

void func2(){ 
    B2 myObj; 
    myObj.foo(); 
    myObj.bar(); 
} 

看一看,研究以下內容:Example

+0

您能否詳細說明'A2'和'B2'? – tMJ 2014-10-20 14:47:23

+0

@tMJ我剛剛做了,看看我附加的例子。它應該說明發生了什麼。 – 2014-10-20 14:52:46

+0

謝謝,讓它更清晰!我還有另外一個問題,我可以在父類中聲明一個方法(我相信沒有父類的實例會創建),並在子類中定義它。這種技術叫做什麼? – tMJ 2014-10-20 14:57:25

1

修復了評論中提到的私人問題,並且爲A :: foo提供了避免「未定義的vtable」錯誤的實現之後,您將看到您正在調用B :: foo這使A :: var單獨出現,但是酒吧打印出A :: var。

在派生類中使用相同的變量名稱相當愚蠢,但我會牢記未來混淆的要求。

A2和B2看起來不那麼超現實。

1

一旦在func中調用foo,foo會設置A :: var或B :: var?

foo將設置B :: VAR

而在呼叫FUNC鍵欄將酒吧閱讀:: VAR或B ::變種?

酒吧FUNC()將返回A ::變種,這將是零或未定義

我是否需要,如果沒有一個 的實例將永遠申報VAR作爲數據成員在一被創建?

是的,因爲它是返回變量的void A :: bar()。

類聲明A2和B2的作用與A和 B的作用相同嗎?

不,A2 :: bar和B2 :: bar將返回相同的var(42)。

0
  1. 在來電FUNC按鍵foo將FOO設置A :: VAR或B ::變種?

foo()是虛擬的,和myObj動態(實際上靜態)類型B,所以這將是B::foo()被調用,設置B::var

請注意,在這種情況下,virtual不起作用,因爲您沒有使用多態。

  1. 而在調用bar中的func時,會看到A :: var或B :: var?

它會讀取A::var

  1. 如果永遠不會創建A的實例,是否需要在A中聲明var作爲數據成員?

你需要做A::bar()虛擬我想,還是有B::foo()呼叫A::foo()在某些點設置基本成員變量。

  1. 類聲明A2和B2的作用與A和B的作用相同嗎?

你認爲他們有什麼不同?