vptr help? [modified]
-
Please tell me how function call is resolve, how vptr works in this case CODE:
class base
{
public:
virtual void f1()
{
cout<<"base f1";
}
virtual void f2()
{
cout<<"base f2";
}
};
class d1: public base
{
public:
virtual void f1()
{
cout<<"d1's f1";
}virtual void f2()
{
cout<<"d1's f2";
}
};
class d2: virtual public base,virtual public d1
{
public:d2() { cout<<"d2 class construxtor\\n"; } ~d2() { cout<<" d2 class destructor\\n"; }
};
void main()
{
clrscr();
base* obj= new d2;
obj->f1();
obj->f2();
}modified on Sunday, July 12, 2009 2:46 PM
-
Please tell me how function call is resolve, how vptr works in this case CODE:
class base
{
public:
virtual void f1()
{
cout<<"base f1";
}
virtual void f2()
{
cout<<"base f2";
}
};
class d1: public base
{
public:
virtual void f1()
{
cout<<"d1's f1";
}virtual void f2()
{
cout<<"d1's f2";
}
};
class d2: virtual public base,virtual public d1
{
public:d2() { cout<<"d2 class construxtor\\n"; } ~d2() { cout<<" d2 class destructor\\n"; }
};
void main()
{
clrscr();
base* obj= new d2;
obj->f1();
obj->f2();
}modified on Sunday, July 12, 2009 2:46 PM
vptrs don't come into it - you have no virtual functions, so therefore there will be no vtable. If the compiler was able to construct your
base
pointerobj
(it can't because it inherits frombase
twice - which one should it upcast through?), there would be no runtime resolution off1
andf2
; they're non-virtual functions, so they will be resolved using the static type ofobj
, i.e.base
. That means that the program (if it could compile) would outputbase f1base f2
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
-
vptrs don't come into it - you have no virtual functions, so therefore there will be no vtable. If the compiler was able to construct your
base
pointerobj
(it can't because it inherits frombase
twice - which one should it upcast through?), there would be no runtime resolution off1
andf2
; they're non-virtual functions, so they will be resolved using the static type ofobj
, i.e.base
. That means that the program (if it could compile) would outputbase f1base f2
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
Actually the code will (and does) compile. Note that
base
is inherited virtually (note the use ofvirtual public base
in the declaration of classd2
). This ensures that only one version of thebase
class will be included ind2
However, you are completely correct in that there is no vtable, and the output wil bebase f1base f2
.Graham Librarians rule, Ook!
-
vptrs don't come into it - you have no virtual functions, so therefore there will be no vtable. If the compiler was able to construct your
base
pointerobj
(it can't because it inherits frombase
twice - which one should it upcast through?), there would be no runtime resolution off1
andf2
; they're non-virtual functions, so they will be resolved using the static type ofobj
, i.e.base
. That means that the program (if it could compile) would outputbase f1base f2
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
all right I got it...but if I am making f1() and f2() virtual in base class and d1 class, how vptr will work?
-
Actually the code will (and does) compile. Note that
base
is inherited virtually (note the use ofvirtual public base
in the declaration of classd2
). This ensures that only one version of thebase
class will be included ind2
However, you are completely correct in that there is no vtable, and the output wil bebase f1base f2
.Graham Librarians rule, Ook!
Better tell that to gcc, then - it gives this warning and error:
a.cpp:30: warning: direct base ‘base’ inaccessible in ‘d2’ due to ambiguity
a.cpp: In function ‘int main()’:
a.cpp:46: error: ‘base’ is an ambiguous base of ‘d2’VC++ 2008 agrees
a.cpp(30) : error C2584: 'd2' : direct base 'base' is inaccessible; already a base of 'd1'
a.cpp(5) : see declaration of 'base'
a.cpp(16) : see declaration of 'd1'The virtual qualifier needs to be applied to all inheritance instances of the shared base, so you need this code for it to compile (note virtual wherever 'base' is inherited):
class base
{
public:
void f1()
{
cout<<"base f1";
}
void f2()
{
cout<<"base f2";
}
};
class d1: virtual public base
{
public:
void f1()
{
cout<<"d1's f1";
}void f2()
{
cout<<"d1's f2";
}
};
class d2: virtual public base, public d1
{
public:d2() { cout<<"d2 class construxtor\\n"; } ~d2() { cout<<" d2 class destructor\\n"; }
};
int main()
{
base* obj= new d2;
obj->f1();
obj->f2();
}Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
-
Better tell that to gcc, then - it gives this warning and error:
a.cpp:30: warning: direct base ‘base’ inaccessible in ‘d2’ due to ambiguity
a.cpp: In function ‘int main()’:
a.cpp:46: error: ‘base’ is an ambiguous base of ‘d2’VC++ 2008 agrees
a.cpp(30) : error C2584: 'd2' : direct base 'base' is inaccessible; already a base of 'd1'
a.cpp(5) : see declaration of 'base'
a.cpp(16) : see declaration of 'd1'The virtual qualifier needs to be applied to all inheritance instances of the shared base, so you need this code for it to compile (note virtual wherever 'base' is inherited):
class base
{
public:
void f1()
{
cout<<"base f1";
}
void f2()
{
cout<<"base f2";
}
};
class d1: virtual public base
{
public:
void f1()
{
cout<<"d1's f1";
}void f2()
{
cout<<"d1's f2";
}
};
class d2: virtual public base, public d1
{
public:d2() { cout<<"d2 class construxtor\\n"; } ~d2() { cout<<" d2 class destructor\\n"; }
};
int main()
{
base* obj= new d2;
obj->f1();
obj->f2();
}Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
OK, you caught me. :-O That'll learn me not to trust VS2005 :doh:
Graham Librarians rule, Ook!
-
all right I got it...but if I am making f1() and f2() virtual in base class and d1 class, how vptr will work?
As base is declared virtual, there is one instance of base in d2. This means (IIUC) that the functions in d1 will hide the functions in base from the point-of-view of d2 because d1 is more derived than base.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
-
OK, you caught me. :-O That'll learn me not to trust VS2005 :doh:
Graham Librarians rule, Ook!
Graham Shanks wrote:
VS2005
That compiled in VS2005? I guess I can understand why, I think. Maybe. Also yet another example why it's good to keep clear of tricksy inheritance features in C++. a) the programmer isn't 100% sure what should happen (I'm definitely including myself in that group), and b) neither's the compiler.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
-
all right I got it...but if I am making f1() and f2() virtual in base class and d1 class, how vptr will work?
For the working of vptr, allow me to redirect you to one of my articles Polymorphism in C[^]
«_Superman_» I love work. It gives me something to do between weekends.
-
Graham Shanks wrote:
VS2005
That compiled in VS2005? I guess I can understand why, I think. Maybe. Also yet another example why it's good to keep clear of tricksy inheritance features in C++. a) the programmer isn't 100% sure what should happen (I'm definitely including myself in that group), and b) neither's the compiler.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
Stuart Dootson wrote:
That compiled in VS2005?
No. Doesn't compile in VS 2005, 2008 or VC++ 6.0.
-
Actually the code will (and does) compile. Note that
base
is inherited virtually (note the use ofvirtual public base
in the declaration of classd2
). This ensures that only one version of thebase
class will be included ind2
However, you are completely correct in that there is no vtable, and the output wil bebase f1base f2
.Graham Librarians rule, Ook!
The code doesn't compile with VC++ 6.0, VS 2005 and VS 2008. (clrscr() is also undeclared in Visual C++; I vaguely recall it being in Turbo C. Perhaps he has an early version of Turbo C++ and it's not showing this as an error.)