ScArfAcE
ScArfAcE

Reputation: 3

Base class function accessing derived class member

Below is an example of what I am trying to do. Basically, my GetInt() function is defined in the base class A, and my derived class B should also use the same definition. But the catch is that, when I access GetInt() from an object of class B, I want to return the derived class's member not the base's one. But the Output of below code gives:

Constructor A called
Constructor A called
Constructor B called
Object A: 10
Object B: 10

whereas I want it to be:

Constructor A called
Constructor A called
Constructor B called
Object A: 10
Object B: 5

My code:

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

Is there any way to do this?

Upvotes: 0

Views: 131

Answers (4)

Vishal Gupta
Vishal Gupta

Reputation: 244

Virtual function is a good option but You can also use this code.

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

In this case when we call the Class B constructor it first call the class A constructor so initialize m_nA with 10. Then in body of class B constructor it override m_nA value with 5. So in this case always gives the correct result as you expected.

Upvotes: 1

Andreas Fester
Andreas Fester

Reputation: 36649

You need to make GetInt() virtual and override it in the sub class:

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

Since you are explicitly calling the method by specifying the type A:: and B::, you do not necessarily need to make it virtual - but you would then not be able to call B::GetInt() through a pointer or reference to A (no late binding):

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

With virtual method:

Object B through A&: 5

With non-virtual method:

Object B through A&: 10

Upvotes: 0

Titus
Titus

Reputation: 927

private:
            int m_nA;

Change the above in base class "A" to "protected". Don't define the member "m_nA" in "class B". Thats it! you are good to go.

Upvotes: 2

BЈовић
BЈовић

Reputation: 64293

You are calling A::GetInt(), and that will always return A::m_nA.

Unless you can change the name of B::m_nA, the only thing you can do it to use virtual functions :

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

Upvotes: 1

Related Questions