Click here to Skip to main content
15,881,172 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
C#
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
Updated 10-Dec-12 20: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. :-)

Some examples:
C++
// 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!
 
Share this answer
 
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
 
Share this answer
 
Comments
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.
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.
 
Share this answer
 
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 :)
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).
 
Share this answer
 
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!
Wendelius 17-Dec-12 14:23pm    
Good answer!
Jibesh 17-Dec-12 15:44pm    
5'ed!!
// which is inturn NOT possible!
:)

// But THIS IS COMPILING
:)

// 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 :)

PS: Something about interfaces:
An abstract interface will be used also to mask an object out:
C++
// 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
}
 
Share this answer
 
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!

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900