Anand
Anand

Reputation: 81

Error: no appropriate default constructor

Not able to compile the following. whats wrong here?

class B;
class A
{
public:
    void DoSomething()
    {
        ...
        B* myb = new B();
        ...
    }
};

class B
{ 
public:
B() {}
};

Upvotes: 0

Views: 253

Answers (4)

aslg
aslg

Reputation: 1974

You do the forward declaration in order to know that some class B exists, although it's not defined yet. In this case you don't even need to do that because there is no member in class A of type B.

Just declare the doSomething method, and define it later after B is defined

class A {
    ...
    void doSomething(); // declared
    ...
};

class B {
    ...
};

// define doSomething after defining class B or in the .cpp source file
void A::doSomething() {
    B *myb = new B();
    ...
}

Though usually you would use header/source files so it would be more practical to separate the declaration from the definition.


EDIT

If both A and B refer to each other then you need to write a forward declaration in one of them (or both).

// A.h
class B;
class A {
    ...
    B *_myB;
};

// A.cpp
#include "B.h"

void A::doSomething() {
    _myB = new B();
}

// B.h
class A;
class B {
    ...
    A *_myA;
};

// B.cpp
#include "A.h"

void B::doSomething() {
    _myA = new A();
}

A forward declaration allows you to have a pointer to that type, such as B*. But not a complete type B, because the size of B is not known but B* is the same size of any other pointer.

You could have made one of them store a complete type by including the other class in the header file, but not both.

Anyway it wouldn't make sense if you could include dependent complete types. Then an instance of A would instantiate a member B which would in turn instantiate its member A, and so on.

Upvotes: 1

Alper
Alper

Reputation: 13250

class B;

The declaration above (forward declaration) introduces the name B into the compiler. After the declaration and before the definition is seen, type B is an incomplete type.

The use of incomplete type is limited. For example, a pointer or a reference can be defined to such type. However, it is not possible;

  • to create objects of that type (compiler doesn't know size of the class)
  • to access a member of that type (compiler doesn't know what member the class has)

In the code in question;

B* myb = new B();

is after the declaration and before the definition is seen.

Upvotes: 0

basav
basav

Reputation: 1495

When you forward declare a type, you are telling the compiler that such a type exists.But the Compiler has no idea about the size or members of that type.

You generally use a forward declaration to break circular dependencies.

class B;
class A
{
public:
    void DoSomething()
    {
        ...
        B* myb ;            ...
    }
};

This will work since you only have a pointer to that type.

This has been discussed in detail here: forward reference usage

Upvotes: 0

Christian Hackl
Christian Hackl

Reputation: 27548

new B() requires the complete definition of the type. A forward declaration is not sufficient.

Which makes sense. For example, who says B even has a public default constructor? You cannot know that before B's complete definition is known.

Upvotes: 1

Related Questions