paradox when constructor of an pure abstract base class called?

Discussion in 'C++' started by ypjofficial@indiatimes.com, Jan 19, 2006.

  1. Guest

    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! ]
    , Jan 19, 2006
    #1
    1. Advertising

  2. wrote:
    > 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
    Victor Bazarov, Jan 19, 2006
    #2
    1. Advertising

  3. * :
    >
    > 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! ]
    Alf P. Steinbach, Jan 19, 2006
    #3
  4. Gavin Deane Guest

    wrote:
    > 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! ]
    Gavin Deane, Jan 19, 2006
    #4
  5. Earl Purple Guest

    wrote:
    > 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! ]
    Earl Purple, Jan 19, 2006
    #5
  6. Daniel T. Guest

    In article <>,
    wrote:

    > 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! ]
    Daniel T., Jan 19, 2006
    #6
  7. Zara Guest

    On 19 Jan 2006 07:06:01 -0500, wrote:

    >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! ]
    Zara, Jan 19, 2006
    #7
  8. mlimber Guest

    wrote:
    > 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! ]
    mlimber, Jan 19, 2006
    #8
  9. Pete Becker Guest

    Earl Purple wrote:
    > 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! ]
    Pete Becker, Jan 19, 2006
    #9
  10. Guest

    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! ]
    , Jan 19, 2006
    #10
  11. kanze Guest

    wrote:

    > 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! ]
    kanze, Jan 20, 2006
    #11
  12. Guest

    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! ]
    , Jan 20, 2006
    #12
  13. Pete Becker wrote:
    > Earl Purple wrote:
    >
    >>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.
    >


    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! ]
    Victor Bazarov, Jan 20, 2006
    #13
  14. "Pete Becker" <> wrote in message
    news:...
    > Earl Purple wrote:
    >> 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.
    >


    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! ]
    Eugene Kalenkovich, Jan 20, 2006
    #14
  15. Gavin Deane Guest

    wrote:

    > 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! ]
    Gavin Deane, Jan 20, 2006
    #15
  16. Jim Langston Guest

    <> wrote in message
    news:...
    > 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! ]
    Jim Langston, Jan 22, 2006
    #16
  17. Ralph Guest

    "mlimber" <> wrote in message
    news:...
    > wrote:
    > > 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
    >


    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! ]
    Ralph, Jan 22, 2006
    #17
  18. Luke Meyers Guest

    Ralph wrote:
    > 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! ]
    Luke Meyers, Jan 23, 2006
    #18
  19. Gavin Deane Guest

    Ralph wrote:

    > 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.

    <snip>

    > 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! ]
    Gavin Deane, Jan 23, 2006
    #19
  20. In article <>, Ralph
    <> writes
    >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! ]
    Francis Glassborow, Jan 23, 2006
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. vsgdp
    Replies:
    7
    Views:
    392
    Ron Natalie
    Sep 25, 2005
  2. Replies:
    10
    Views:
    707
    Richard Herring
    Oct 18, 2005
  3. Replies:
    4
    Views:
    792
    Rolf Magnus
    May 17, 2006
  4. Arne Schmitz
    Replies:
    4
    Views:
    414
    Daniel Albuschat
    Jan 17, 2007
  5. Marcel Müller
    Replies:
    2
    Views:
    96
    Marcel Müller
    Mar 15, 2014
Loading...

Share This Page