2

I want to ask what happen, when I use virtual functions without pointers ? for example:

#include <iostream>
using namespace std;
class Parent
{
 public:
   Parent(int i) { }
   virtual void f() { cout<<"Parent"<<endl; }
};

class Child : public Parent
{
 public:
   Child(int i) : Parent(i) { }
   virtual void f() { Parent::f(); cout<<" Child"<<endl; }
};

int main()
{
    Parent a(2);
    Parent b = Child(2);
    a.f();
    b.f();
    return 0;
}

^^ Why doesn't it work ? Where can I find something about how virtual methods really work?

Artjom B.
  • 61,146
  • 24
  • 125
  • 222
yProgrammer
  • 173
  • 1
  • 4
  • 1
    Another question (probably one of many) addressing the same issue that you can read for further insight: http://stackoverflow.com/questions/2931423/problem-overridding-virtual-function/2931438 – Tyler McHenry Aug 30 '10 at 11:03
  • @Tyler - This question is basically an exact duplicate of that one. Voting to close. – Omnifarious Aug 30 '10 at 11:09
  • The code is the same; the underlying assumption is not. Here, the problem is assumed to be in the _calling_ of the virtual function. The linked question assumed the failure to be in the _overriding_ of the virtual function. (Of course, the real cause in both was slicing). So I'm inclined to say that it's not identical. – MSalters Aug 30 '10 at 12:00

3 Answers3

14

This effect is called "slicing."

Parent b = Child(2); // initializes a new Parent object using part of Child obj

In C++, the dynamic type may only differ from the static type for references or pointers. You have a direct object. So, your suspicion was essentially correct.

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
  • 4
    This is getting upvoted like crazy, but it's not a very good answer. Kirill provided a reference, check out that. – Potatoswatter Aug 30 '10 at 11:06
  • I was thinking that, and embarked on my own answer, then read the link and realized the answers at the end of it are just as good as any I'd write. :-) This question should be closed as an exact duplicate. – Omnifarious Aug 30 '10 at 11:11
  • 1
    How do you need a wikipedia link if you yourself explained already? People can google if or look elsewhere if they want more information. Personally I like this one much more than the wikipedia one, +1. – Johannes Schaub - litb Aug 30 '10 at 11:24
4

Try the following:

std::auto_ptr<Parent> b = new Child(2);

In your code you copy part of Child object to b. This is so called object slicing.

Kirill V. Lyadvinsky
  • 97,037
  • 24
  • 136
  • 212
1

Virtual function mechanism is enabled only if the virtual function is called through either an appropriate reference or an appropriate pointer. Note that virtual function call mechanism is suppressed in constructor/destructor or while using the :: operator.

If the code is as shown below, virtual function mechanism will be enabled.

Child c;
Parent &a = c;
a.f();

Without pointers, the call is statically bound, even if it is a virtual function call.

EDIT 2:

$10.3/6 - [Note: the interpretation of the call of a virtual function depends on the type of the object for which it is called (the dynamic type), whereas the interpretation of a call of a nonvirtual member function depends only on the type of the pointer or reference denoting that object (the static type) (5.2.2). ]

Chubsdad
  • 24,777
  • 4
  • 73
  • 129