Advertisement

virtual and class inherience

Started by September 01, 2013 07:31 PM
11 comments, last by Bregma 11 years, 5 months ago

Virtual function calls would allow exactly that, so within constructors and destructors, calls to the object's member functions are all treated as non-virtual.

No, they are still treated as virtual, but the dynamic type is that of the class that defined the constructor/destructor whose body is currently being executed. Consider the output of the following code:

struct A {
  void non_virtual_func() { std::cout << "A::non_virtual_func()\n"; }
  virtual void virtual_func() { std::cout << "A::virtual_func()\n"; }
};

struct B : A {
  B() {
    A * a = this;
    a->non_virtual_func();
    a->virtual_func();
  }

  void non_virtual_func() { std::cout << "B::non_virtual_func()\n"; }
  virtual void virtual_func() { std::cout << "B::virtual_func()\n"; }
};

struct C : B {
  C() {
    A * a = this;
    a->non_virtual_func();
    a->virtual_func();
  }

  void non_virtual_func() { std::cout << "C::non_virtual_func()\n"; }
  virtual void virtual_func() { std::cout << "C::virtual_func()\n"; }
};

int main(int, char **) {
  B b;
  std::cout << std::endl;
  C c;
  std::cout << std::endl;
  return 0;
}

Virtual function calls would allow exactly that, so within constructors and destructors, calls to the object's member functions are all treated as non-virtual.

No, they are still treated as virtual...

Haha - your code is making calls to some object pointed to by a pointer, which just happens to be the same object. This demonstrates that - yeah - the object is "not yet a derived type object".

But as far as calls made directly to members within a constructor, the same function gets called whether its treated as non-virtual or as virtual (on an object which is "currently" of base type). I don't know for sure, but I'm not sure the compiler is required to pay the virtual function call overhead in this case.

Advertisement


You can make a non-virtual call from within a virtual function though which is sometimes needed (not for destructors though, which automatically call the base class destructors)

You can. It's a code smell, though. It violates the LSP.. "Public inheritance is substitutability. Inherit, not to reuse, but to be reused." If you find yourself calling up the chain like this, consider redesigning your code to use the non-virtual interface idiom. It will make you a happier, better person and your laundry will come out whiter and brighter.

Stephen M. Webb
Professional Free Software Developer

This topic is closed to new replies.

Advertisement