Reputation: 3567
Had a complicated program that kept throwing up the missing default constructor error, and after much tinkering, i found the exact same scenario that gives the same error. What's wrong with this?
class B;
class A
{
public:
A() {instance = new B;}
virtual ~A() {delete instance;}
private:
A*instance;
};
class B : public A
{
public:
B(){}
}
can't forward declare a derived class to be used within the base class?
Upvotes: 0
Views: 113
Reputation: 114461
c++ rules about how forward the compiler is going to look are not obvious (for example it's ok to use instance
in a method even if the member is defined later in the class but it's not ok to use a class defined later in the same source file).
In this case the problem (as the other reported) is that when compiling new B
the compiler must know more about B
than just it's a class and it will not keep reading past the class A
to look what a B
really is.
One possible solution is to put the definition of A
constructor and destructor later (still leaving them inlined):
class B;
class A
{
public:
A();
virtual ~A();
private:
A *instance;
};
class B : public A
{
public:
B() {}
};
inline A::A() { instance = new B; }
inline A::~A() { delete instance; }
This compiles but however will not run correctly because indeed what you're trying to do here is quite confused.
To create an instance of A
you want to create an instance of B
, but B
is a specialization of A
and therefore when you create an instance of B
you will be also creating an instance of A
(the A
base sub-object of B
).
This means that to create an instance of A
you need indirectly to create an instance of A
.
Sounds loopy, doesn't it?
Instantiating an instance of A
(or of B
) with this code will lead to infinite recursion (i.e. a strange crash on most implementations).
Upvotes: 0
Reputation: 993
No. Because the derived class may contain additional elements. so you cant use that to initialize base class object with derived class object.
Upvotes: -1
Reputation: 18964
You need to put the definition (but not the declaration) of A's constructor outside A, after the definition of B. Using B in A is OK as long as you don't need it to be complete (fully defined) - and new B
definitely does.
Upvotes: 0
Reputation: 263098
How can new B
succeed if the compiler doesn't know anything about class B
yet? If you move the member function implementations out of class A
below the definition of class B
, it should work:
class A
{
public:
A();
virtual ~A();
private:
A * instance;
};
class B : public A
{
public:
B(){}
};
A::A()
{
instance = new B;
}
A::~A()
{
delete instance;
}
What exactly are A and B, anyway? Having a base class instantiate a derived class sure is a bit unusual.
Upvotes: 2