Click here to Skip to main content
15,881,033 members
Please Sign up or sign in to vote.
4.00/5 (2 votes)
See more:
C++

Hi All!
The below code works fine VS6.0, but In VS2005,2008 it is giving compilation Error C2559: "cannot instantiate an abstract class"
Due to Derived class calling base class(abstract class) constructor.

Please lets give the solution.

Thanks
Arjun


C++
class Base
{
public:
    int a;
    Base()
    {
        cout<<"Base::Base()"<<endl;
    }
    virtual void f1()= 0;

    ~Base()
    {
        cout<<"Base::~Base()"<<endl;
    }

};

class Derived : public Base
{
public:
    Derived()
    {
        cout<<"Derived::Derived()"<<endl;
    }
    void f1()
    {
        cout<<"Derived::f1()"<<endl;
    }

    void f2()
    {
        Base::Base();  //Cannot instantiate an abstract class

    }
    ~Derived()
    {
        cout<<"Derived::~Derived()"<<endl;
    }
};


Edit by Aescleal: Added code tags so lesser mortals like me can read it...
Posted
Updated 14-May-12 23:50pm
v2

The error message says it all really, it's what any sane compiler should give you for the code you've written. You're trying to create an instance of Base which is abstract.

In case you don't know, you're trying to create the instance of base when you write Base::Base(). It's an unnamed temporary that'll be constructed and destructed immediately but there's still a request to make an object in there.

The only way you're going to make base something you can create instances of is to remove the pure virtual ( = 0 ) from f1 and give it an implementation. Nothing else will do...

And if it "worked" in VC++6.0 that's yet another reason to bury that compiler under several feet of rock and treat it like it's intensely radioactive.

Cheers,

Ash

PS: With reference to the comment below...

Repeat after me - you are not calling the constructor, you're trying to create an instance of an object. It's a bit confusing as in C++:
C++
Base::f1();

means "explicitly call f1() as found in the class Base on whatever the current object is" but:
C++
Base::Base();

means "reserve a lump of memory big enough for an object of class Base, call it's default constructor on that memory, call it's destructor then drop the memory back in the bit bucket."


Anyway, just remember you don't call constructors (even when using placement new, although it comes close) the compiler does for you and ONLY when initialising a new object from raw memory.
 
Share this answer
 
v3
Comments
tgm.arjun09 15-May-12 6:18am    
Hi! The C2559 error is getting only when i'm calling Base class(abstract class) constructor from derived class function. like.. Base::Base().

But it is not giving error for base class normal func Base::Func.

And i should need to use the pure virtual in base class, i should not to change. that is the requirement.
I'm afraid I'm not able to think of an instance where one would _want_ to call a base class's constructor in a derived class's member function. Forgive me if I overlook a situation that this is required.

That would mean that if one were to declare an instance of Derived, following this with a call to instanceDerived->f2(), that the base constructor would be called twice. My feeling is that you should have another function (say, init) that was called from the Base class's constructor. You then have the option of invoking this init method from within your f2() member function.

Here, this works just fine in VS2010 (your code had same errors that you reported):

C++
// deleteMe.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>

using std::cout;
using std::endl;

class Base
{
public:
    int a;
    Base()
    {
        cout<<"Base::Base()"<<endl;
		// alloc mem here
		//
		//
		someNumber = new int;

		// init alloced mem to some value
		init();
    }
    virtual void f1()= 0;
 
    ~Base()
    {
        cout<<"Base::~Base()"<<endl;
		delete someNumber;
    }

	void init()
	{
		*someNumber = rand()%128;
	}
protected:
	int *someNumber;
};
 
class Derived : public Base
{
public:
    Derived()
    {
        cout<<"Derived::Derived()"<<endl;
    }
    void f1()
    {
        cout<<"Derived::f1()"<<endl;
    }
 
    void f2()
    {
		cout << "f2()" << endl;
		//---  Base::Base();  //Cannot instantiate an abstract class ----
		// don't want to call Base::Base here, since that will re-alloc (i.e allocate for a 2nd or more time)
		
		// BUT, we would like to reset the allocated mem to the default values
		init();
    }

	int getSomeNumber()
	{
		return *someNumber;
	}

    ~Derived()
    {
        cout<<"Derived::~Derived()"<<endl;
    }
};



int _tmain(int argc, _TCHAR* argv[])
{
	{
		Derived a;
		int tmp;

		a.f2();
		tmp = a.getSomeNumber();
		cout << "tmp = " << tmp << endl;

		a.f2();
		tmp = a.getSomeNumber();
		cout << "tmp = " << tmp << endl;

		a.f2();
		tmp = a.getSomeNumber();
		cout << "tmp = " << tmp << endl;
	}
	getchar();
	return 0;
}


Output:
Base::Base()
Derived::Derived()
f2()
tmp = 35
f2()
tmp = 62
f2()
tmp = 4
Derived::~Derived()
Base::~Base()
 
Share this answer
 
v2
Comments
tgm.arjun09 15-May-12 7:01am    
Hi! Your solution works great! But can you plz tell me, why it is not giving error in VS6.0. why it is giving error in VS2005 and later versions?
enhzflep 15-May-12 7:08am    
Wonderful!
Not sure exactly what's happening behind the scenes, though Ash's statement
"And if it "worked" in VC++6.0 that's yet another reason to bury that compiler under several feet of rock and treat it like it's intensely radioactive"
is a ripper!

MS are known for doing non-standard things with their compilers, as is GCC etc.
Thankfully, this inclusion of extra "features" is declining with time.

VS still allows this:
class Base{
public:
Base::Base();
};

While gcc will baulk at such a statement, requiring that it be changed to:

class Base{
public:
Base();
};

Found this gem recently in the headers for GDI+ for what it's worth.

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