2013-02-13 70 views
3

這是代碼,我很難理解:由於父保護構造函數,C++不能實例化一個子類?

class A 
{ 
protected: 
    int _i; 
    A() : _i(0) { } 
    ~A() { } 
}; 

class B: public A 
{ 
public: 
    A *_pa; 
    B() : A(), _pa(new A()) 
    { } 

    ~B() 
    { 
     delete _pa; 
    } 
}; 

int main() 
{ 
    A a; //ERROR 
    B b; //ERROR 
} 

當試圖實例化一個類A型我得到一個錯誤,因爲它的構造是受保護的。但爲什麼我不能實例化類型B?該課程可以訪問A(包括ctor)的受保護成員,因此應該編譯。

+2

也粘貼錯誤和它出現的行。 – iammilind 2013-02-13 13:51:50

+0

爲什麼你想要一個成員類指針_and_繼承的類型'A'? – 2013-02-13 13:52:47

+0

@TylerJandreau顯然,他只是測試受保護的構造函數... – 2013-02-13 13:54:18

回答

4

您的錯誤位於B構造函數內new A,而不是調用super的構造函數。

讓我來解釋一下protected的工作原理。如果您有一個B類別,它是A的子類,它不能訪問受保護的元素A,它在處理B引用時可以訪問受保護的元素A

爲了表明我的觀點:

#include <iostream> 

class A { 
protected: 
    int a; 
}; 

class B : public A { 
public: 
    void do_it(A* a) { 
     std::cout << a->a << std::endl; //ERROR 
    } 
    void do_it(B* a) { 
     std::cout << a->a << std::endl; //VALID CODE 
    } 
}; 

我想這種行爲背後的原因是,如果你有一個三等C這也訪問A保護的成員,或許這不是一個好主意,別人變化這些受保護的值。

+0

嗯所以這是因爲'new'在全局範圍內 – Tom 2013-02-13 14:46:41

+0

@Tom否,'new'在B上下文中,如果沒有使用B引用就無法訪問A. 'new A'是一個指向A的指針,而不是B,所以你不能訪問它的構造函數...... – 2013-02-13 14:52:10

0

您在main中有錯誤。在那裏你不能實例化A,因爲它的構造函數是受保護的。

另外,你不能調用_pa的構造函數B.

的構造
+0

我知道,但我不能實例化B既不。我明白爲什麼A不會工作 – Tom 2013-02-13 13:57:39

3

從A派生只允許您訪問您通過「本」或通過其他硼。硼沒有按」訪問受保護的成員無法訪問_pa的受保護成員。

-1

在構造函數B,A構造函數被調用。由於A的構造函數受到保護,因此在B的構造函數中調用A的構造函數時出現錯誤。同樣在A的保護範圍內,有析構函數。當B的析構函數被調用時,它的基類(A)的析構函數也被調用。因爲A的析構函數受到保護,所以還會出現另一個錯誤。如果從的構造函數中取出A的構造函數,則仍然顯示錯誤。但是你可以在公佈A的析構函數後襬脫錯誤。

public: 
    ~A() { } 

這個扣除通過檢查代碼塊給出的錯誤,但似乎是錯誤的。刪除_pa(new A())是確切的解決方案@ @AndréPuel的答案更正確。

相關問題