paradox when constructor of an pure abstract base class called?

Y

ypjofficial

Hello All,

I have following doubt..

class abstractclass
{
public:
abstractclass(){}
virtual void method()=0;
};

class concreteclass:public abstractclass
{
public:
concreteclass(){}
void method(){}
};

void main()
{

concreteclass c;
}

now when I create the object of concreteclass, the constructor of
abstractclass will be called.and as per the logic constructors are
called while creating the object,object of abstractclass is being
created..so how come we can create an object of a abstract class?
or to put in another way is there any paradox when the constructor of
an abstract class gets called?

Thanks and Regards,
Yogesh Joshi


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
V

Victor Bazarov

I have following doubt..

class abstractclass
{
public:
abstractclass(){}
virtual void method()=0;
};

class concreteclass:public abstractclass
{
public:
concreteclass(){}
void method(){}
};

void main()

int main()
{

concreteclass c;
}

now when I create the object of concreteclass, the constructor of
abstractclass will be called.and as per the logic constructors are
called while creating the object,object of abstractclass is being
created..so how come we can create an object of a abstract class?

We can, only as a subobject of another object. We can't create
a _stand-alone_ object of abstract class.
or to put in another way is there any paradox when the constructor of
an abstract class gets called?

No.

V
 
A

Alf P. Steinbach

* (e-mail address removed):
class abstractclass
{
public:
abstractclass(){}
virtual void method()=0;
};

class concreteclass:public abstractclass
{
public:
concreteclass(){}
void method(){}
};

void main()
{

concreteclass c;
}

'main' must have result type 'int'.

If your compiler accepts the above, then it's non-conforming in this
respect.

now when I create the object of concreteclass, the constructor of
abstractclass will be called.and as per the logic constructors are
called while creating the object,object of abstractclass is being
created..so how come we can create an object of a abstract class?
or to put in another way is there any paradox when the constructor of
an abstract class gets called?

The reason C++ forbids you to instantiate an abstract class on its own
is that it's not meaningful: an abstract class _depends_ on its pure
virtual functions to do the crucial things (that's why it's abstract).

As a base class part of another object those pure virtual functions are
defined, by the derived class, i.e. you have totally different
situation, and that's the whole point, the way it's meant to be used.

However, there is a possibility of erronously calling a pure virtual
function from the abstract class constructor, via some other member
function. The result of that is undefined behavior, but most likely it
will be detected and cause a crash. It simply means that static
(compile-time) type checking and rules based on such checking can not
protect against all run-time errors, which we knew anyway.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
G

Gavin Deane

Hello All,

I have following doubt..

class abstractclass
{
public:
abstractclass(){}
virtual void method()=0;
};

class concreteclass:public abstractclass
{
public:
concreteclass(){}
void method(){}
};

void main()

This should be int main() by the way.
{

concreteclass c;
}

now when I create the object of concreteclass, the constructor of
abstractclass will be called.and as per the logic constructors are
called while creating the object,object of abstractclass is being
created..so how come we can create an object of a abstract class?
or to put in another way is there any paradox when the constructor of
an abstract class gets called?

Your premise is that it is impossible, by definition, to create an
instance of an abstract class. This leads you think that you have a
logical paradox when an instance of abstractclass is created within
concreteclass. However, your premise is wrong.
From 10.4/2
An abstract class is a class that can be used only as a base class of
some other class; no objects of an abstract class can be created except
as subobjects of a class derived from it.

Couldn't be clearer. If you apply logic to an incorrect premise, you
shouldn't be surprised if the conclusion you reach doesn't make sense.

Gavin Deane


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
E

Earl Purple

Hello All,

I have following doubt..

class abstractclass
{
public:
abstractclass(){}
virtual void method()=0;
};

class concreteclass:public abstractclass
{
public:
concreteclass(){}
void method(){}
};

void main()
{

concreteclass c;
}

now when I create the object of concreteclass, the constructor of
abstractclass will be called.and as per the logic constructors are
called while creating the object,object of abstractclass is being
created..so how come we can create an object of a abstract class?
or to put in another way is there any paradox when the constructor of
an abstract class gets called?

Just because its constructor gets called doesn't mean you have an
instance of it.

And main should return int.
And you should really give your abstract base class a virtual
destructor in case anyone holds a pointer to one created with new.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
D

Daniel T.

Hello All,

I have following doubt..

class abstractclass
{
public:
abstractclass(){}
virtual void method()=0;
};

class concreteclass:public abstractclass
{
public:
concreteclass(){}
void method(){}
};

void main()
{

concreteclass c;
}

now when I create the object of concreteclass, the constructor of
abstractclass will be called.and as per the logic constructors are
called while creating the object,object of abstractclass is being
created..so how come we can create an object of a abstract class?
or to put in another way is there any paradox when the constructor of
an abstract class gets called?

Yes, there is. For example if 'method()' (or any other virtual
member-function) is called from within the abstractclass c_tor.

--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
Z

Zara

Hello All,

I have following doubt..

class abstractclass
{
public:
abstractclass(){}
virtual void method()=0;
};

class concreteclass:public abstractclass
{
public:
concreteclass(){}
void method(){}
};

void main()
{

concreteclass c;
}

now when I create the object of concreteclass, the constructor of
abstractclass will be called.and as per the logic constructors are
called while creating the object,object of abstractclass is being
created..so how come we can create an object of a abstract class?
or to put in another way is there any paradox when the constructor of
an abstract class gets called?

Thanks and Regards,
Yogesh Joshi

The only "paradox" you may speak of, is that from the moment that
abstractclass object is completely constructed till the moment that
concreteclass is completely constructed, you may try to call method()
with undefined results.

Regards,

Zara

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
M

mlimber

Hello All,

I have following doubt..

class abstractclass
{
public:
abstractclass(){}
virtual void method()=0;
};

class concreteclass:public abstractclass
{
public:
concreteclass(){}
void method(){}
};

void main()

int main()

See http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.3
{

concreteclass c;
}

now when I create the object of concreteclass, the constructor of
abstractclass will be called.
Correct.

and as per the logic constructors are
called while creating the object,object of abstractclass is being
created..so how come we can create an object of a abstract class?

Because the derived class is a kind of the base class. Think of the
classic example with Shape and Circle classes. Shape is an abstract
concept that doesn't make sense to instantiate on its own (what would
the area of a Shape be?). But when you instantiate a Circle, you have
instantiated a kind of Shape, and the area can be calculated according
to the concrete class' implementation.
or to put in another way is there any paradox when the constructor of
an abstract class gets called?

Nope.

Cheers! --M


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
P

Pete Becker

Earl said:
And you should really give your abstract base class a virtual
destructor in case anyone holds a pointer to one created with new.

Base classes should have virtual destructors only if their design calls
for deleting objects of derived types through pointers to the base.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
V

v.manojkumar

Hi,

the constructor of abstractclass will be called.
This is absoulutly right. Understand the "ISA" rule... the
derived class is
a base class+ something extra.
and as per the logic constructors are
called while creating the object,object of abstractclass is being
created.. so how come we can create an object of a abstract class?

Now this isnt creaing a abstract object... this is creating the
base part
of the derived object which eventually happens to be abstract.

The basic logic is if a pure virtual function is present... then if the
compiler
allows creation of objects then... the function call to that fn is
undefined...

--
manoj


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
K

kanze

I have following doubt..
class abstractclass
{
public:
abstractclass(){}
virtual void method()=0;
};
class concreteclass:public abstractclass
{
public:
concreteclass(){}
void method(){}
};
void main()
{

concreteclass c;
}
now when I create the object of concreteclass, the constructor
of abstractclass will be called.and as per the logic
constructors are called while creating the object,object of
abstractclass is being created.. so how come we can create an
object of a abstract class? or to put in another way is there
any paradox when the constructor of an abstract class gets
called?

Sort of. During the construction of abstractclass, the dynamic
type of the object under construction is abstractclass -- it's
the most derived type.

I think that the answer is that you don't have a complete object
until all of the constructors have run. And the restriction is
that you cannot have a complete object of type abstractclass.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
K

kamil.pawlowski

For proper destructor semantics, isn't the abstract class required to
declare a virtual destructor as well?

For example this code:
#include <stdio.h>

class A {
public:
A(){};
virtual void foo() = 0;
//virtual ~A(){ printf("~A\n"); }
};

class B : public A {
public:
B() : A() {}
virtual void foo(){ printf("foo!\n"); }
virtual ~B(){ printf("~B\n"); }
};

int main(int argc, char** argv){
A* a = dynamic_cast<A*>( new B() );
a->foo();
delete a;
}

will print:
$ ./a.exe
foo!

Where as commenting back in:
virtual ~A(){ printf("~A\n"); }

will lead to the proper
$ ./a.exe
foo!
~B
~A


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
V

Victor Bazarov

Pete said:
Base classes should have virtual destructors only if their design calls
for deleting objects of derived types through pointers to the base.

That's generally true. But is there any _real_ harm in declaring the
destructor virtual if there is already virtual functions present? I will
stipulate that in some rare cases growing the virtual function table by
one entry could take it over the top (the straw that broke the camel's
back), but that instance is unlikely, no?

Or a related topic:
I vaguely remember some conversation here or in c.l.c++.m, or in c.s.c++,
to make the compiler-provided destructor virtual by if there is at least
one virtual function present, has there been any resolution on it?

V

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
E

Eugene Kalenkovich

Pete Becker said:
Base classes should have virtual destructors only if their design calls
for deleting objects of derived types through pointers to the base.

Presence of virtual functions in class makes this call pretty loud...

-- EK


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
G

Gavin Deane

For proper destructor semantics, isn't the abstract class required to
declare a virtual destructor as well?

You must have a virtual destructor *if* you intend to delete a derived
class object via a pointer to the base class, as you did in your code
example.

But the use of an abstract class does not necessarily imply polymorphic
deletion is going to happen. For example, the OP's code was correct in
this respect without a virtual destructor. So the answer to your
question is: No, the abstract class is not *required* to declare a
virtual destructor.

In practice, I'm sure the majority of abstract classes do have virtual
destructors because they are (or could in the future be) deleted
polymorphically.

Gavin Deane


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
J

Jim Langston

Hello All,

I have following doubt..

class abstractclass
{
public:
abstractclass(){}
virtual void method()=0;
};

class concreteclass:public abstractclass
{
public:
concreteclass(){}
void method(){}
};

void main()
{

concreteclass c;
}

now when I create the object of concreteclass, the constructor of
abstractclass will be called.and as per the logic constructors are
called while creating the object,object of abstractclass is being
created..so how come we can create an object of a abstract class?
or to put in another way is there any paradox when the constructor of
an abstract class gets called?

Thanks and Regards,
Yogesh Joshi

Short answer. You can not instantiate a pure virtual class. So you can't
create an object of your abstractclass.

Long answer, read everyone else's replies.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
R

Ralph

mlimber said:
int main()

See http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.3


Because the derived class is a kind of the base class. Think of the
classic example with Shape and Circle classes. Shape is an abstract
concept that doesn't make sense to instantiate on its own (what would
the area of a Shape be?). But when you instantiate a Circle, you have
instantiated a kind of Shape, and the area can be calculated according
to the concrete class' implementation.


Nope.

Cheers! --M

mlimber,

While everyone has provided very sage, excellent answers to your question,
appreciate that you can ignore their admonishments concerning "int main()".
If your compiler accepts it, consider yourself lucky and go on about your
business.

It is true that the current C++ standard requires "int main()", ie "There
shall be a 'main()' and its signature shall be "int main()", its signature
shall not be "void main()", nor shall it be "long main()", but its name
shall be "int main()", blah, blah, ..."

However, this particular standard is an unfortunate platform-specific
implimentation feature that should never have been part of an
"implementation-free" language standard. In reality every compiler replaces
the entry-point compiler keyword "main" with another function (and startup
code) based on its signature and the platform and libraries used for the
compile.

It is also a reality that all implemented c runtimes today only accept a
'int' return to the OS (might not always be true - it would be up to the
vendor) and if one is not provided the implemenation dependent 'main()'
provides one for you. So the 'void' or 'int' return is only to provide the
compiler with a clue as to whether or not to generate a warning or error if
your code does or doesn't include a return statement. Which is identical and
proper compiler behavior when syntax-checking any function.

-ralph



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
L

Luke Meyers

Ralph said:
While everyone has provided very sage, excellent answers to your question,
appreciate that you can ignore their admonishments concerning "int main()".
If your compiler accepts it, consider yourself lucky and go on about your
business.

It is true that the current C++ standard requires "int main()", ie "There
shall be a 'main()' and its signature shall be "int main()", its signature
shall not be "void main()", nor shall it be "long main()", but its name
shall be "int main()", blah, blah, ..."

However, this particular standard is an unfortunate platform-specific
implimentation feature that should never have been part of an
"implementation-free" language standard. In reality every compiler replaces
the entry-point compiler keyword "main" with another function (and startup
code) based on its signature and the platform and libraries used for the
compile.

Whether it belongs in the standard or not is arguable -- what is not
arguable is that it IS in the standard. Making a generalization that
"every compiler" does something which is not mandated by the standard
is just begging to be proven wrong by the next perfectly
standard-compliant compiler to come down the pike.

I wouldn't tell someone to be happy that their compiler accepted "void
main" without complaint -- I'd tell them to crank up their warnings
settings or get a better compiler. "void main" is not portable, in the
sense that a compliant compiler can consider it an error. A *good*
compiler will certainly generate a warning for it, and a good C++
programmer will configure that compiler to treat warnings as errors.
So, even if you're perfectly happy to disable that warning or ignore
it, or use a compiler too dumb to generate it, your code is still
non-portable.

What happens is that someone takes your non-compliant code and tries to
compile it on an appropriately strict compiler, which generates the
warning and treats it as an error. On this setup, which is better than
the one you're using, the code fails to compile. The other programmer
must now either adjust his compiler settings to accommodate your code
(if he or she knows how), or fix your code for you.

And what the hell, anyway? "int" is *easier* to type than "void." Why
go out of your way to violate the standard? Why encourage less
experienced C++ programmers to do the same? As standards violations
go, this is obviously a minor one, but surely you've got better things
to do than encourage people to rely on their own personal
interpretations of which parts of the standard do and don't apply to
them.

</tirade> (you know you were begging for it)

Luke


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
G

Gavin Deane

Ralph said:
While everyone has provided very sage, excellent answers to your question,
appreciate that you can ignore their admonishments concerning "int main()".
If your compiler accepts it, consider yourself lucky and go on about your
business.

But do bear in mind that when you upgrade your compiler, or change to a
different one, or change compiler settings, or port your code, it might
not compile any more. It won't be hard to fix, of course.

So the 'void' or 'int' return is only to provide the
compiler with a clue as to whether or not to generate a warning or error if
your code does or doesn't include a return statement. Which is identical and
proper compiler behavior when syntax-checking any function.

int main() {}

is a correct program. A compiler would be wrong to benerate an error.

Gavin Deane


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
F

Francis Glassborow

Ralph said:
It is also a reality that all implemented c runtimes today only accept a
'int' return to the OS (might not always be true - it would be up to the
vendor) and if one is not provided the implemenation dependent 'main()'
provides one for you. So the 'void' or 'int' return is only to provide the
compiler with a clue as to whether or not to generate a warning or error if
your code does or doesn't include a return statement. Which is identical and
proper compiler behavior when syntax-checking any function.

No, C++ explicitly allows the omission of a return statement from main
and specifies that in such a case 'falling off the end of main' is
implicitly a 'return 0'

There is absolutely no reason for not specifying the correct return type
(it even saves you a keystroke:)


--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top