1

I have three following classes:

class A
{
private:
    std::string device;
public:
    std::string getDeviceType() { return device; };
    void setDeviceType(std::string device) { device = device; };
    virtual void doSomething() = 0;
    virtual void doSomething2() = 0;
};

class B: public A
{
    private:
    public:
        B(){ ; };
        virtual ~B(){ ; };
        void doSomething() { std::cout << "I am usual B" << std::endl; };
        void virtual doSomething2() { std::cout << "I am usual B" << std::endl; };
};

class C : public B
{
private:
public:
    C(){ ; };
    ~C(){ ; };
    void doSomething() { std::cout << "I am C" << std::endl; };
    void doSomething2() { std::cout << "I am C" << std::endl; };
};

main:

B *myHandler = new C();
myHandler->doSomething();
myHandler->doSomething2();

but output is not as expected, my expected output was I am usual B and then I am C, because doSomething() is a non virtual member of class B. But the real output was I am C and then I am C. Do you know why?

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
wair92
  • 446
  • 11
  • 24
  • [OT] `{ device = device; }` should be `{ this->device = device; }`, or use different names. – Jarod42 Aug 08 '17 at 12:00
  • 3
    Overridden methods stay virtual; Since `A::doSomething` is, `B::doSomething` and `C::doSomething` are too, regardless of the repetition of the keyword `virtual` in their declaration. – YSC Aug 08 '17 at 12:03

3 Answers3

6

because of doSomething() is non virtual member of class B

This is where you are mistaken. In A you declare doSomething() as virtual. That means that it is implicitly marked virtual in classes that derive from it. So doSomething() in B is virtual which means you will call C's doSomething().

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
4

The reason is that doSomething is marked as virtual in class A. So it remains virtual in classes B and C because they inherit from class A.

As this function is virtual, it is called according to the real type of the object, which is C in your case, and you get the output: I am C.

Edgar Rokjān
  • 17,245
  • 4
  • 40
  • 67
0

Once marked virtual, it remains virtual in all derived classes.

In C you overrode both doSomething() and doSomething2(). You instantiate C, so the methods of C are called in both cases.

If you omitted the override in C of doSomething(), the output would be as you expected it.

KR, Melle

melle
  • 26
  • 5