2

I have already searched a lot on the web, but I haven't found anything that might solve my problem. I have these classes:

File: A.h

#include "B.h"

class A {
...
B method();
}

File: B.h

#include "A.h"

class B : public A {
...
}

I'm getting this error "expected class-name before ‘{’ token" in B class file. I've tried add the class declaration in A.h as well as in B.h, but nothing worked. I guess this is a circular dependency problem. Does anyone could help me?

Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
Lucas
  • 33
  • 1
  • 7

3 Answers3

0

This is called "forward declaration". For example:

#include "B.h"

class B;

class A {
...
B method();
};

As long as you only declare the method, and don't actually define it, this makes it possible to declare the method.

An actual C file will include both header files, and with the definitions of both classes, now the class method can be defined, or invoked and used.

You might want to start looking at the standard C++ headers like <iostream>, <string>, and others. All the templates in the C++ library typically have complex mutual dependencies on each others.

You will probably find that your C++ compiler has structured its headers in a fairly strict order. First come all the forward declarations and the class declarations. And only after everything is declared, only then you'll see the actual template declarations.

That's pretty much the only possible way it can be done.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
0

The following works for me. If you're still having problems you should provide an mvce.

Foo.h

#ifndef FOO_H
#define FOO_H

class Bar; // Forward declaration

// Note: I'm not sure why this interface knows anything about the derived type
class Foo
{
public:
    // Omitted the virtual destructor in this example

    Bar& try1();
    const Bar& try2() const;

    Bar try3() const;

    Bar* try4();
    const Bar* try5() const;
};

#endif

Foo.cpp

#include "Foo.h"

#include "Bar.h"

Bar& Foo::try1()
{
    return static_cast<Bar&>(*this);
}

const Bar& Foo::try2() const
{
    return static_cast<const Bar&>(*this);
}

Bar Foo::try3() const
{
    return Bar();
}

Bar* Foo::try4()
{
    return static_cast<Bar*>(this);
}

const Bar* Foo::try5() const
{
    return static_cast<const Bar*>(this);
}

Bar.h

#ifndef BAR_H
#define BAR_H

#include "Foo.h"

class Bar : public Foo
{
};

#endif

main.cpp

#include "Foo.h"
#include "Bar.h"

int main()
{
    Foo f;
    f.try1();
    f.try2();
    f.try3();
    f.try4();
    f.try5();

    return 0;
}
Community
  • 1
  • 1
James Adkison
  • 9,412
  • 2
  • 29
  • 43
0

There are a number of solutions to your problem but the best one is tailored to the design of your classes (which we don't know anything about). However, the following will resolve your problem, even if it doesn't follow an ideal design pattern:

  1. Forward declare class B inside A.h and above class A definition.
  2. Make sure you only use pointers or references to class B objects within A.h member function declarations.
  3. Include B.h in A.cpp. NOTE the .cpp not .h

A.h

class B;

class A
{
public:
    A();
    ~A();

    B* method();
};

A.cpp

#include "A.h"
#include"B.h"

A::A()
{
}


A::~A()
{
}

B* A::method()
{
    return nullptr;
}

Please note there are virtues in only passing in, and returning, pointers / references to user defined types so this might not be a bad choice, particularly if you are only looking for a quick fix.

Serge
  • 634
  • 4
  • 9