访问派生类成员的基类函数

时间:2014-10-30 08:41:23

标签: c++ class inheritance

以下是我想要做的一个例子。基本上,我的GetInt()函数在基类A中定义,而我的派生类B也应该使用相同的定义。但问题是,当我从类GetInt()的对象访问B时,我想要返回派生类的成员而不是基类的成员。但是下面代码的输出给出了:

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;
}

有没有办法做到这一点?

4 个答案:

答案 0 :(得分:2)

private:
            int m_nA;

将基类“A”中的上述内容更改为“protected”。 不要在“B类”中定义成员“m_nA”。 而已!你很高兴。

答案 1 :(得分:1)

您正在呼叫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;
};

答案 2 :(得分:1)

虚拟功能是一个不错的选择,但您也可以使用此代码。

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值。所以在这种情况下总是给出正确的结果你期待的。

答案 3 :(得分:0)

您需要使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()通过指针或对A的引用(没有后期绑定):

A& ObjAb = ObjB;
std::cout << "Object B through A&: " << ObjAb.GetInt() << std::endl;

使用虚拟方法:

Object B through A&: 5

使用非虚方法:

Object B through A&: 10