473,396 Members | 1,875 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Can abstract base class have V-table?, Will the pointer to virtual destructor be entered into the virtual table?

Hi all,

I'm a new to c++... and I've some doubts on "virtual" topics.

1) Can abstract base class have V-table?

Here's the way,,

Class CTemp{

CTemp(){};
~CTemp(){};

virtual void display() = 0;

virtual void draw() { cout << " It's ready!!" << endl;}
}

Class CDerived : public CTemp{

CDerived(){};
~CDerived(){};

}

Can this class CTemp have a v-table?

2) Will the virtual destructor be entered into the virtual table?

please give me good directions..

With rgds
soj

Apr 6 '06 #1
12 4952
Sojin
Can this [abstract] class CTemp have a v-table?
Class Ctemp cannot have an object of his type since it is virtual,
hence if there is no class there is no v-table? Right? Or do not I
understand your question?
2. Will the virtual destructor be entered into the virtual table?


But you have not declared the destructor virtual to start with?

Marc Wentink

Apr 6 '06 #2
sojin wrote:
Hi all,

I'm a new to c++... and I've some doubts on "virtual" topics.

1) Can abstract base class have V-table?

Here's the way,,

Class CTemp{

CTemp(){};
~CTemp(){};

virtual void display() = 0;

virtual void draw() { cout << " It's ready!!" << endl;}
}

Class CDerived : public CTemp{

CDerived(){};
~CDerived(){};

}

Can this class CTemp have a v-table?
Yes

2) Will the virtual destructor be entered into the virtual table?
Yes

please give me good directions..

With rgds
soj

Apr 6 '06 #3

sojin wrote:
Hi all,

I'm a new to c++... and I've some doubts on "virtual" topics.

1) Can abstract base class have V-table?

Here's the way,,

Class CTemp{

CTemp(){};
~CTemp(){};

virtual void display() = 0;

virtual void draw() { cout << " It's ready!!" << endl;}
}

Class CDerived : public CTemp{

CDerived(){};
~CDerived(){};

}

Can this class CTemp have a v-table?

2) Will the virtual destructor be entered into the virtual table?

please give me good directions..

With rgds
soj

yes even though the class is abstract it does have a vtable, in that
at least on entry for a function is zero.

Apr 6 '06 #4
1. For every class if it contains at least one virtual function (or
pure virtual function) V-TABLE will be formed. In the case of pure
virtual fucntions , the corresponding entry of the VTABLE will be NULL.
When you are trying to instantiate any object of the class, runtime
will check if the VTABLE will have any NULL entries, if it's so it
won't alllow you to create any objects of that class.

2. As per above, virtual destructor also be entered into the virtual
table as it's a virtual function.
al pacino wrote:
sojin wrote:
Hi all,

I'm a new to c++... and I've some doubts on "virtual" topics.

1) Can abstract base class have V-table?

Here's the way,,

Class CTemp{

CTemp(){};
~CTemp(){};

virtual void display() = 0;

virtual void draw() { cout << " It's ready!!" << endl;}
}

Class CDerived : public CTemp{

CDerived(){};
~CDerived(){};

}

Can this class CTemp have a v-table?

2) Will the virtual destructor be entered into the virtual table?

please give me good directions..

With rgds
soj

yes even though the class is abstract it does have a vtable, in that
at least on entry for a function is zero.


Apr 6 '06 #5
sojin wrote:
Hi all,

I'm a new to c++... and I've some doubts on "virtual" topics.

1) Can abstract base class have V-table?
There is nothing in the Standard that mandates virtual functions be
provided via vtable. It's an implementation detail. Therefore the
answer to this question is undefined. Granted, all current
implementations use a vtable, but it is not required. Assuming a vtable
implementation, the answer is it will *always* have a vtable.
2) Will the virtual destructor be entered into the virtual table?


As there is no requirement for a vtable, the answer to this question is
undefined. However, assuming a vtable implementation, the answer is yes.
Apr 6 '06 #6
Thanks for your reply.... my queries ends here....
now i'm digging to the deep....
sojin....

Apr 6 '06 #7
ma*********@hotmail.com wrote:
Sojin
Can this [abstract] class CTemp have a v-table?

Note that vtables are implementation artifacts. They are not defined by
the C++ language.
Class Ctemp cannot have an object of his type since it is virtual,
hence if there is no class there is no v-table?


There certainly is a class. You might thing that since CTemp cannot be
instantiated by itself, there is no need for a vtable. However, during
the construction of a CDerived object, there is a brief moment during
which the object is considered to be a CTemp, and is not yet a
CDerived.

That happens when the CTemp constructor has been entered, but the
CDerived constructor has not yet been. During this time, if virtual
functions are called, they have to go to CTemp definitions.

This cannot be implemented statically, because a constructor can run
arbitrary code which doesn't know what type the object is:

void LibraryFunction(CTemp *basePtr)
{
basePtr->virtualFunction();
}

CTemp::CTemp()
{
LibraryFunction(this);
}

The virtualFunction() call in LibraryFunction has to
CTemp::virtualFunction even though the object is really a CDerived, and
there is a CDerived::virtualFunction.

LibraryFunction cannot do this by clairvoyance: it has to retrieve some
type-related information from the object, such as a vtable pointer.

Even if CTemp is a pure abstract base class (pure virtuals only) so
that the call to virtualFunction is actually a pure virtual call error,
there still has to be something in the object to detect that run-time
error.

Quite conceivably, if the base class has nothing but pure virtuals,
perhaps the vtable could be optimized away. The vtable pointer in the
partially constructed object could just be set to some special value
(like null). (But then the run-time system would not be able to
provide a diagnostic which distinguishes between a pure virtual call
error, and a virtual call on an object that has been stomped-over with
zero bytes).

Apr 6 '06 #8

"red floyd" <no*****@here.dude> wrote in message
news:w1*******************@newssvr12.news.prodigy. com...
sojin wrote:
Hi all,

2) Will the virtual destructor be entered into the virtual table?


As there is no requirement for a vtable, the answer to this question is
undefined. However, assuming a vtable implementation, the answer is yes.


And also assuming that the destructor was actually declared as virtual in
the first place! :-) (It wasn't virtual in the code given.)

-Howard
Apr 6 '06 #9
marcwent...@hotmail.com wrote:
Sojin
Can this [abstract] class CTemp have a v-table?

Note that vtables are implementation artifacts. They are not defined by
the C++ language.
Class Ctemp cannot have an object of his type since it is virtual,
hence if there is no class there is no v-table?


There certainly is a class. You might think that since CTemp cannot be
instantiated by itself, there is no need for a vtable. However, during
the construction of a CDerived object, there is a brief moment during
which the object is considered to be a CTemp, and is not yet a
CDerived.

That happens when the CTemp constructor has been entered, but the
CDerived constructor has not yet been. During this time, if virtual
functions are called, they have to go to CTemp definitions.

This cannot be implemented statically, because a constructor can run
arbitrary code which doesn't know what type the object is:

void LibraryFunction(CTemp *basePtr)
{
basePtr->virtualFunction();
}

CTemp::CTemp()
{
LibraryFunction(this);
}

The virtualFunction() call in LibraryFunction has to
CTemp::virtualFunction even though the object is really a CDerived, and
there is a CDerived::virtualFunction.

LibraryFunction cannot do this by clairvoyance: it has to retrieve some
type-related information from the object, such as a vtable pointer.

Even if CTemp is a pure abstract base class (pure virtuals only) so
that the call to virtualFunction is actually a pure virtual call error,
there still has to be something in the object to detect that run-time
error.

Quite conceivably, if the base class has nothing but pure virtuals,
perhaps the vtable could be optimized away. The vtable pointer in the
partially constructed object could just be set to some special value
which summarizes the idea that the object is a pure ABC. Of course,
the code generated for virtual calls would then have to check for this
value to detect pure virtual calls.

(Null would be a poor choice for this value, because, then the run-time
system would not be able to provide a diagnostic which distinguishes
between a pure virtual call
error, and a virtual call on an object that has been stomped-over with
zero bytes).

In a sense, that special value could still be considered a vtable,
albeit a compressed, summarized one.

Apr 6 '06 #10

Okay, well I've a lot of free time today.
First of all, look at the following code:
#include <some_header_that_defines_geometrical_shapes>
#include <iostream>
using std::cout; using std::endl; using std::cin;

void PrintObjectInfo( ThreeDimensionalObject& object )
{
cout << object.GetClassification() << "\n\nMass: " << object.GetMass()
<<
"\n\nSurface Area: " << object.GetSurfaceArea() << "\n\n";
}
int main()
{
Sphere sphere; sphere.radius = 5;

Cylinder cylinder; cylinder.height = 2; cylinder.radius = 7;
PrintObjectInfo( sphere );
PrintObjectInfo( cylinder );
}
The idea in the code above is that the member functions,
"GetClassification", "GetMass" and "GetSurfaceArea" should be virtual so
that the function "PrintObjectInfo" can call the appropriate functions.

I've written a self-sufficient source code file to demonstrate (please keep
reading as it gets interesting):

//normal.cpp

class ThreeDimensionalObject
{
public:
virtual const char* GetClassification() const = 0;
virtual unsigned long GetMass() const = 0;
virtual unsigned long GetSurfaceArea() const = 0;
};

class Sphere : public ThreeDimensionalObject
{
public:
unsigned long radius;

virtual const char* GetClassification() const { return "Sphere"; }

virtual unsigned long GetMass() const
{
return (radius * radius * radius) * 3 / 3;
}

virtual unsigned long GetSurfaceArea() const
{
return radius * radius * 3;
}
};

class Cylinder : public ThreeDimensionalObject
{
public:
unsigned long radius;
unsigned long height;

virtual const char* GetClassification() const { return "Cylinder"; }

virtual unsigned long GetMass() const
{
return radius * height;
}

virtual unsigned long GetSurfaceArea() const
{
return height * 2 / radius;
}
};

#include <iostream>
using std::cout; using std::endl; using std::cin;

void PrintObjectInfo( ThreeDimensionalObject& object )
{
cout << object.GetClassification() << "\n\nMass: " << object.GetMass()
<<
"\n\nSurface Area: " << object.GetSurfaceArea() << "\n\n";
}
int main()
{
Sphere sphere; sphere.radius = 5;

Cylinder cylinder; cylinder.height = 2; cylinder.radius = 7;
PrintObjectInfo( sphere );
PrintObjectInfo( cylinder );
}
So then I thought, how would I achieve this if C++ didn't have virtual
functions? I'd have to implement the whole V-table concept by myself.

Step 1: I'm going to have to change the original code slightly:
#include <some_header_that_defines_geometrical_shapes>

#include <iostream>
using std::cout; using std::endl; using std::cin;

void PrintObjectInfo( ThreeDimensionalObject& object )
{
cout << object.vtable->GetClassification(&object) << "\n\nMass: " <<
object.vtable->GetMass(&object) <<
"\n\nSurface Area: " << object.vtable->GetSurfaceArea(&object) <<
"\n\n";
}
int main()
{
Sphere sphere; sphere.radius = 5;

Cylinder cylinder; cylinder.height = 2; cylinder.radius = 7;
PrintObjectInfo( sphere );
PrintObjectInfo( cylinder );
}
Here comes the code I spent the last half hour writing... enjoy!

//weird.cpp
struct VTable {};

// Forward Declarations
struct ThreeDimensionalObject;
struct Sphere;
struct Cylinder;

struct VTable_ThreeDimensionalObject : public VTable {
//Pointers to functions

const char* (*GetClassification)(const ThreeDimensionalObject*);
unsigned long (*GetMass)(const ThreeDimensionalObject*);
unsigned long (*GetSurfaceArea)(const ThreeDimensionalObject*);

VTable_ThreeDimensionalObject(
const char* (*In_GetClassification)(const ThreeDimensionalObject*),
unsigned long (*In_GetMass)(const ThreeDimensionalObject*),
unsigned long (*In_GetSurfaceArea)(const ThreeDimensionalObject*) )
: GetClassification(In_GetClassification), GetMass(In_GetMass),
GetSurfaceArea(In_GetSurfaceArea) {}

};

struct VTable_Sphere : public VTable_ThreeDimensionalObject {

//Nothing extra to add in here

VTable_Sphere(
const char* (*In_GetClassification)(const ThreeDimensionalObject*),
unsigned long (*In_GetMass)(const ThreeDimensionalObject*),
unsigned long (*In_GetSurfaceArea)(const ThreeDimensionalObject*) )
: VTable_ThreeDimensionalObject
(In_GetClassification,In_GetMass,In_GetSurfaceArea ) {}

};

struct VTable_Cylinder : public VTable_ThreeDimensionalObject {

//Nothing extra to add in here

VTable_Cylinder(
const char* (*In_GetClassification)(const ThreeDimensionalObject*),
unsigned long (*In_GetMass)(const ThreeDimensionalObject*),
unsigned long (*In_GetSurfaceArea)(const ThreeDimensionalObject*) )
: VTable_ThreeDimensionalObject
(In_GetClassification,In_GetMass,In_GetSurfaceArea ) {}
};
//Forward declarations:
extern VTable_ThreeDimensionalObject vtable_threedimensionalobject;
extern VTable_Sphere vtable_sphere;
extern VTable_Cylinder vtable_cylinder;
//Now define the classes:

struct ThreeDimensionalObject {

VTable_ThreeDimensionalObject* vtable;

ThreeDimensionalObject() : vtable( &vtable_threedimensionalobject ) {}

protected:

ThreeDimensionalObject( VTable_ThreeDimensionalObject* p ) : vtable(p)
{}
};

struct Sphere : public ThreeDimensionalObject {

Sphere() : ThreeDimensionalObject( &vtable_sphere ) {}

unsigned long radius;
};
struct Cylinder: public ThreeDimensionalObject {

Cylinder() : ThreeDimensionalObject( &vtable_cylinder ) {}

unsigned long radius;
unsigned long height;
};
//Define the actual functions

const char* GetClassification_Sphere( const ThreeDimensionalObject* ) {
return "Sphere"; }

unsigned long GetMass_Sphere( const ThreeDimensionalObject* p )
{
Sphere const &sphere = *static_cast<const Sphere*>(p);

return (sphere.radius * sphere.radius * sphere.radius) * 3 / 3;
}

unsigned long GetSurfaceArea_Sphere( const ThreeDimensionalObject* p )
{
Sphere const &sphere = *static_cast<const Sphere*>(p);

return sphere.radius * sphere.radius * 3;
}

const char* GetClassification_Cylinder( const ThreeDimensionalObject* ) {
return "Cylinder"; }

unsigned long GetMass_Cylinder(const ThreeDimensionalObject* p)
{
Cylinder const &cylinder = *static_cast<const Cylinder*>(p);

return cylinder.radius * cylinder.height;
}

unsigned long GetSurfaceArea_Cylinder(const ThreeDimensionalObject* p)
{
Cylinder const &cylinder = *static_cast<const Cylinder*>(p);

return cylinder.height * 2 / cylinder.radius;
}
//Define the vtable objects:

VTable_ThreeDimensionalObject vtable_threedimensionalobject(0, 0, 0);

VTable_Sphere vtable_sphere( GetClassification_Sphere, GetMass_Sphere,
GetSurfaceArea_Sphere );

VTable_Cylinder vtable_cylinder( GetClassification_Cylinder,
GetMass_Cylinder, GetSurfaceArea_Cylinder );
#include <iostream>
using std::cout; using std::endl; using std::cin;

void PrintObjectInfo( ThreeDimensionalObject& object )
{
cout << object.vtable->GetClassification(&object) << "\n\nMass: " <<
object.vtable->GetMass(&object) <<
"\n\nSurface Area: " << object.vtable->GetSurfaceArea(&object) <<
"\n\n";
}
int main()
{
Sphere sphere; sphere.radius = 5;

Cylinder cylinder; cylinder.height = 2; cylinder.radius = 7;
PrintObjectInfo( sphere );
PrintObjectInfo( cylinder );
}
Okay so I've alleviated by boredom for about an hour. What next?
-Tomás
Apr 6 '06 #11
"Tom?s" <NU**@null.null> wrote:
So then I thought, how would I achieve this if C++ didn't have virtual
functions? I'd have to implement the whole V-table concept by myself.

[snip manual implementation of vtables]

In a similar vein, have you seen Alf P. Steinbach's "Pointers" document?
(Specifically the section on Polymorphism):
http://home.no.net/dubjai/win32cpptu...ters/ch_01.pdf

(You obviously understand what you're doing, but this is for those
following along at home who might not quite follow what you did.)

--
Marcus Kwok
Apr 6 '06 #12
> There certainly is a class. You might think that since CTemp cannot be
instantiated by itself, there is no need for a vtable.


But that was a wrong assumption from my side. Thanks for the lesson!
It gave me more understanding of the VT concept. :-)

Apr 7 '06 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Joe Vrba | last post by:
I'm building a family of components derived from UserControl. There's an abstract base class to ensure basic functionality and then numerous other controls derived from that. The problem is...
3
by: Sunny | last post by:
Hi again, in the past I have posted here a problem with static methods and abstract classes, and Jon Skeet and Richard Lowe have helped me to clarify the things. But now I have found another...
3
by: Jeff | last post by:
I have an abstract class which uses System.Windows.Forms.UserControl as it's base class. It has some custom drawing methods and it also handles a few common events like Paint, PaintBackGround,...
18
by: Bradley | last post by:
I'm trying to determine if there's a general rule for when an Interface should used vs. an Abstract Class. Is there any design advantage to using one or the other? Brad
9
by: Sean Kirkpatrick | last post by:
To my eye, there doesn't seem to be a whole lot of difference between the two of them from a functional point of view. Can someone give me a good explanation of why one vs the other? Sean
7
by: jason | last post by:
In the microsoft starter kit Time Tracker application, the data access layer code consist of three cs files. DataAccessHelper.cs DataAcess.cs SQLDataAccessLayer.cs DataAcccessHelper appears...
5
by: =?Utf-8?B?UmljaA==?= | last post by:
Greetings, I am actually a VB.Net guy, but I have worked somewhat with C++ and C#. I just want to ask about the relationship between Abstract Classes and Interfaces. My first question is if...
5
by: Tony Johansson | last post by:
Hello! Here I have an Interface called ITest and a class called MyClass which derive this intrface. As you can see I don't implement this method myTest in class MyClass because i use the...
4
by: Israel | last post by:
Can someone explain to me why I get a compiler error with the following code on the line obj.DoSomething()? but if cast the object I get no error. The error I get is: Cannot access protected...
21
by: Mr.SpOOn | last post by:
Hi, I'm going to work on a project to represent some musical theory in Python, in an object oriented way. I have to manage many elements of music such as notes, intervals, scales, chords and so...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.