簡體   English   中英

基類函數訪問派生類成員

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

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