![](/img/trans.png)
[英]Accessing private member of base class using derived class member function
[英]Base class function accessing derived class member
下面是我嘗試做的一個例子。 基本上,我的GetInt()
函數是在基類A
定義A
,而我的派生類B
也應使用相同的定義。 但是要注意的是,當我從類B
的對象訪問GetInt()
,我想返回派生類的成員而不是基類的成員。 但是下面的代碼輸出給出:
Constructor A called
Constructor A called
Constructor B called
Object A: 10
Object B: 10
而我希望它是:
Constructor A called
Constructor A called
Constructor B called
Object A: 10
Object B: 5
我的代碼:
class A{
public:
A(){
std::cout << "Constructor A called" << std::endl;
m_nA = 10;
}
int GetInt(){
return m_nA;
}
private:
int m_nA;
};
class B : public A{
public:
B(){
std::cout << "Constructor B called" << std::endl;
m_nA = 5;
}
private:
int m_nA;
};
int main(){
A ObjA; B ObjB;
std::cout << "Object A: " << ObjA.A::GetInt() << std::endl;
std::cout << "Object B: " << ObjB.B::GetInt() << std::endl;
return 0;
}
有什么辦法嗎?
private:
int m_nA;
將上面的基類“ A”更改為“保護”。 不要在“ B類”中定義成員“ m_nA”。 而已! 你已准備好出發。
您正在調用A::GetInt()
,它將始終返回A::m_nA
。
除非您可以更改B::m_nA
的名稱,否則只有使用虛函數才能做到這一點:
class A{
public:
A() : m_nA(10){
std::cout << "Constructor A called" << std::endl;
}
virtual int GetInt(){
return m_nA;
}
private:
int m_nA;
};
class B : public A{
public:
B() : A(), m_nA(5){
std::cout << "Constructor B called" << std::endl;
}
virtual int GetInt(){
return m_nA;
}
private:
int m_nA;
};
虛函數是一個不錯的選擇,但是您也可以使用此代碼。
class A{
public:
A(){
std::cout << "Constructor A called" << std::endl;
m_nA = 10;
}
int GetInt(){
return m_nA;
}
protected:
int m_nA;
};
class B : public A{
public:
B(){
std::cout << "Constructor B called" << std::endl;
m_nA = 5;
}
};
在這種情況下,當我們調用B類構造函數時,它首先調用A類構造函數,因此用10初始化m_nA。然后在B類構造函數的主體中,它用5覆蓋m_nA值。因此,在這種情況下,始終提供正確的結果。
您需要將GetInt()
虛擬化並在子類中重寫它:
class A{
public:
A(){
std::cout << "Constructor A called" << std::endl;
m_nA = 10;
}
virtual int GetInt(){
return m_nA;
}
private:
int m_nA;
};
class B : public A{
public:
B(){
std::cout << "Constructor B called" << std::endl;
m_nA = 5;
}
virtual int GetInt(){
return m_nA;
}
private:
int m_nA;
};
Constructor A called
Constructor A called
Constructor B called
Object A: 10
Object B: 5
由於您是通過指定類型A::
和B::
顯式調用該方法的,因此不必將其設置為虛擬的-但是您將無法通過指針或B::GetInt()
引用來調用B::GetInt()
A
(無后期綁定):
A& ObjAb = ObjB;
std::cout << "Object B through A&: " << ObjAb.GetInt() << std::endl;
用虛方法:
Object B through A&: 5
使用非虛擬方法:
Object B through A&: 10
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.