Click here to Skip to main content
12,068,967 members (70,416 online)
Rate this:
 
Please Sign up or sign in to vote.
See more: C++ C# Inheritance
class ISample //Interface
{
public:
 
    ISample()
    {
        cout<<"ISample default constructor!!!";
    }
 
    ~ISample()
    {
        cout<<"ISample default destructor!!!";
    }
    virtual void add() = 0;
    virtual void diff() = 0;
};
 
class Base : ISample //still an Abstract class
{
    int n;
 
    public:
 
        Base()
        {
            cout<<"Base default constructor!!!";
            n=0;
        }
 
        Base(int val) : ISample() //calling Interface constructor
        {
            cout<<"Base param constructor!!!";
        }
 
    virtual void add()
    {
 
    }
    virtual void diff() = 0;
};
 
class Der:Base //Derived class
{
    int a;
 
public:
    Der()
    {
        cout<<"Der default constructor!!!";
        a=0;
    }
 
    Der(int val) : Base(val) ////calling Abstract class constructor
    {
        cout<<"Der param constructor!!!";
    }
 
     void add()
    {
        cout<<"Derived add function!!!";
    }
 
    virtual void diff()
    {
        cout<<"Derived diff function!!!";
    }
};
 
int main()
{
    Der obj2(10); //creating an instance of Derived class
}
 
Note: In the above scenario the construcor of interface and abstarct class is getting called from the derived class constructor. Does it NOT mean that creating an instance of Interface / abstract class?? which is inturn NOT possible! But THIS IS COMPILING.
Posted 10-Dec-12 21:07pm
Edited 10-Dec-12 21:16pm
v2
Comments
ThatsAlok 11-Dec-12 2:25am
   
you have concrete constructor and destructor in interface! how this possible if it is compiling! which compiler are you using ?
akchandra9 11-Dec-12 3:01am
   
That is what thrilled me!! i just added c&d in the interface expecting a definite error to be thrown, instead it got executed! yes, i'm using Visual C++.
CPallini 11-Dec-12 3:44am
   
In C++ is perfectly legal: abstract classes (note there is no interface keyword in the language) may contain implementations (however you cannot instantiate them).
ThatsAlok 11-Dec-12 4:32am
   
agreed! i am doing too much c# these day.. just forget there is no keyword like abstract class in C++, to make class abstract you have define pure virtual function...

Is there anyway where i could vote for your comment :-)
CPallini 11-Dec-12 4:59am
   
Sometimes I do the opposite. :-)
akchandra9 11-Dec-12 5:26am
   
I'm still not clear as of how the constructor of an abstract class is getting called, contrary to the fact that we can NOT create an instance of an abstract class!
Can someone tell me where i'm leading the wrong path!! Thank you.
CPallini 11-Dec-12 6:18am
   
Constructor is available: it is a reasonable choice, in my opinion:
You cannot have an instance (object) of the abstract class itself. However you may have an instance of the derived class. Since the derived class may inherit members (e.g. data members) from the abstract class then makes sense to allow it calling the abstract class constructor in order to initialize such members.
JackDingler 11-Dec-12 11:19am
   
I think the constructor has been covered well.

You have a problem with the destructor though. You need to make it virtual if you want it to get called.

Constructors are effectively virtual by default...
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 3

A C++ abstract class is not, by default an interface, i.e. it may contain functionality implementation as well.
As documentation[^] states:


A class that contains at least one pure virtual function is considered an abstract class.


that is it might contain method implementations as well (it is also shown in the linked documentation sample code).
  Permalink  
Comments
ThatsAlok 11-Dec-12 4:32am
   
Voted as mentioned in Question Comment
CPallini 11-Dec-12 4:45am
   
Thank you very much, Alok!
Espen Harlinn 17-Dec-12 12:39pm
   
5'ed!
Mika Wendelius 17-Dec-12 14:23pm
   
Good answer!
jibesh 17-Dec-12 15:44pm
   
5'ed!!
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 5

A constructor starts by invoking constructors for its bases, then constructors for its members, and then executing its code (if any)".

Whether you class has virtual member functions, pure or otherwise, has nothing to do with this. One thing to be aware of though, is that it's impossible to call virtual functions of derived classes during construction or destruction.

In C++ we consider those objects to not exist because either their constructor has not been called, or, in the case of destructors, they no longer exist - even if the memory they occupied is still allocated.

Best regards
Espen Harlinn
  Permalink  
Comments
Mika Wendelius 17-Dec-12 14:23pm
   
Good clarification
Espen Harlinn 17-Dec-12 15:36pm
   
Thank you Mika, the first line is Bjarnes way of phrasing it
Stefan_Lang 18-Dec-12 6:43am
   
Actually, while calling a virtual (or abstract) function from your constructor has undefined behaviour, some compilers may still allow it. Technically it works as long as you don't access member variables that haven't been initialized yet.

I cannot think of a good use case for (ab)using this however: if you know that you won't access any of the not yet initialized member variables of any derived class, then there's little reason for that function to be virtual to start with...
Espen Harlinn 18-Dec-12 7:00am
   
It's not undefined, 12.7.4 says:
Member functions, including virtual functions (10.3), can be called during construction or destruction (12.6.2). When a virtual function is called directly or indirectly from a constructor (including the mem-initializer or brace-or-equal-initializer for a non-static data member) or from a destructor, and the object to which the call applies is the object under construction or destruction, the function called is the one defined in the constructor or destructor’s own class or in one of its bases, but not a function overriding it in a class derived from the constructor or destructor’s class, or overriding it in one of the other base classes of the most derived object
Stefan_Lang 18-Dec-12 7:26am
   
Interesting - thanks for pointing this out.

That said, even armed with that knowledge I'd rather not use them, if only to avoid confusion for anyone looking at the code later.
Espen Harlinn 18-Dec-12 7:33am
   
It can become a source trouble, but sometimes the alternative is so awkward I just go ahead and do it anyway.
Sergey Alexandrovich Kryukov 29-Dec-12 20:57pm
   
Explained. A 5.
—SA
Espen Harlinn 30-Dec-12 5:25am
   
Thank you, Sergey :-D
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 1

// which is inturn NOT possible!
Smile | :)

// But THIS IS COMPILING
Smile | :)

// Does it NOT mean that creating an instance of Interface / abstract class??
The instance will be created implicitly, as a part of a Der-object.
Hence any member of ISample/Base would be counted to sizeof(Der).

But yes, you are right,
it is inpossible to create an indifferent (without diff()) instance directly Smile | :)

PS: Something about interfaces:
An abstract interface will be used also to mask an object out:
// client.h
void test(ISample* pISample)
{
  // Please note:
  // the user-function can not see the real object behind the interface
  if (pISample) {
    pISample->HowAreYou();
  }
}
 
// Sample.h
class ISample
{
public:
  virtual void HowAreYou() = 0;
};
 
// MaskedObject.h
#include "Sample.h"
class MaskedObj : public ISample
{
// here are "megabytes" of own masked Info...
//...

// Test
  void SomeFunction();
 
// Sample functionality:
public:
  virtual void HowAreYou() { MyMessageBox("Fine, thank you!"); }
};
 
// MaskedObj.cpp
#include "client.h"
void MaskedObj::SomeFunction()
{
  ::test(this); // the test-function will know me as an Interface only and not as a MaskedObj
}
  Permalink  
v3
Comments
akchandra9 11-Dec-12 2:35am
   
Thank You!
But can you brief me about the abstract class concept there?? You mean, creating an instance of an abstract class IS possible. but not directly?!
Correct me!
Eugen Podsypalnikov 11-Dec-12 2:43am
   
Maybe, I could :)
An abstract class (for example: an animal)
could hold the all centered data (age, weight, ... of an animal)
or centerd functions (get_age(), ...)
but not implement one or more of the "needed functions"
(for example: "go to", "jump to", "swim to", "say hello", ...).
Any "not abstracted" animal must reimplement the "personal" functions in its own manner :)
akchandra9 11-Dec-12 3:04am
   
Thank you! that's Helpfull! :)
I need more information Regarding what's not be done using abstract classes!
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 4

I'm still not clear as of how the constructor of an abstract class is getting called, contrary to the fact that we can NOT create an instance of an abstract class!
Can someone tell me where i'm leading the wrong path!! Thank you.
  Permalink  
Comments
Eugen Podsypalnikov 11-Dec-12 5:59am
   
Some entries of the virtual functions table of an abstract class
can not be created by its owner object
(that is why "ISample aSample" would be an error for the compiler),
they must be defined by the derived objects.

The instances of the abstract classes
are only accessable per such derivations.

In C++, any not-private base-constructor's call
is possible from any its derivation-constructor :)
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 6

Some examples:
// abstract base class using default constructor implicitely
class IDefaultBase {
public:
 
   // constructor not defined:
   // implicitely defines default constructor IDefaultBase::IDefaultBase()

   // destructor. Must be virtual!
   virtual ~IDefaultBase() {}
 
   // some abstract method
   virtual void print() const = 0;
};
 
class CDefaultDerived : public IDefaultBase {
public:
 
   // constructor not defined:
   // implicitely defines default constructor CDefaultDerived::CDefaultDerived()
   // this constructor automatically calls IDefaultBase::IDefaultBase()

   // destructor. Should be virtual!
   virtual ~CDefaultDerived() {}
 
   // implement abstract method
   virtual void print() const {
      std::cout << "This is CDefaultDerived" << std::endl;
   }
};
 
class CExplicitDerived : public IDefaultBase {
public:
 
   // explicitly defined default constructor
   // implicitely calls constructor IDefaultBase::IDefaultBase()
   CExplicitDerived() {}
 
   // another explicitly defined constructor
   // explicitly calls base constructor, even though it's not required
   CExplicitDerived(int i) : IDefaultBase() {}
 
   // destructor. Should be virtual!
   virtual ~CExplicitDerived() {}
 
   // implement abstract method
   virtual void print() const {
      std::cout << "This is CExplicitDerived" << std::endl;
   }
};
 
// abstract base class without default constructor
class IExplicitBase {
public:
 
   // some explicit non-default constructor
   IExplicitBase(const char* text) {
      // call to non-virtual function:
      print ("This is CExplicitbase");
   }
 
   // virtual destructor
   virtual ~IExplicitBase() {}
 
   // some abstract method
   virtual void print() const = 0;
 
   // some other method
   void print(const char* text) const {
      std::cout << text << std::endl;
   }
};
 
class CExplicit : public Base IExplicitBase {
public:
 
   // must define constructor:
   // base class constructor must be called explicitly!
   CExplicit() : IExplicitBase("This is CExplicit") {}
 
   // attention: this destructor is not virtual
   // this may be a problem if you try to derive another class from this one!
   // but it is legal and works if you don't
   ~CExplicit();
 
   // implement abstract method
   virtual void print() const {
      print("Printing from CExplicit");
   }
};
Note how I did not call the abstract method print() from the constructor of IExplicit: by the time this constructor is called, the derived class is not initialized yet, so any call to a virtual function can have undefined results!
  Permalink  

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


Advertise | Privacy | Mobile
Web02 | 2.8.160208.1 | Last Updated 18 Dec 2012
Copyright © CodeProject, 1999-2016
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100