0

I'm having an issue writing a class as part of a C++ program - in it I have three classes, FirstClass, SecondClass, and ThirdClass - First and Second classes both include ThirdClass.h, and in SecondClass I can declare them normally, however, in FirstClass the first declaration works fine, but any further declarations give me an error that "ThirdClass is not a type name"

here's a snippet from the class that's erroring

#include "ThirdClass.h"

class FirstClass
{
public:

    FirstClass(void);

    // This decleration of ThirdClass works fine
    FirstClass(ThirdClass ());
    FirstClass(const FirstClass& rhs);
    ~FirstClass(void);

private:

    //These are the two that're erroring
    ThirdClass nestedClass();

    void Init (ThirdClass ());
    void Copy (FirstClass);
};

I'm assuming that it's something to do with both of them linking to the same header file, but i've been looking far and wide trying to find a solution online to no avail. I did manage to get it working by placing the include inside a namespace, but I also read that this was very bad practice so I don't really want to do it that way.

Caesar
  • 9,483
  • 8
  • 40
  • 66
  • Note: Defining functions/methods with `void` parameters is depricated. `FirstClass(void)` should be `FirstClass()`. – masoud Dec 31 '12 at 15:28
  • Is this your actual code? What do you really want to do? Do you want `FirstClass` to have a member object of type `ThirdClass` named `nestedClass` (which you _don't_ have) or do you want `FirstClass::nestedClass` to be a function that returns a `ThirdClass` object (which you _do_ currently have). I see some extra `()` that you _probably_ don't want, but it's not clear from your question. – Chad Dec 31 '12 at 15:59
  • 1
    @MasoudM. it's not formally deprecated, it's just bad style and looked on with disgust by people with good taste. It has rightly been described as "an abomination". – Jonathan Wakely Dec 31 '12 at 16:06
  • 1
    Declare your classes where ever you want them and use forward declarations in other header files. For example add the following statemet at the start of your code "class ThirdClass". This tells the compiler that you will declare thirdClass somewhere else in your project. If you end up forgeting to actually define thirdClass, you will get a linker error, otherwise you should be fine – Dr Deo Dec 31 '12 at 16:12
  • Thanks for the information on style and whatnot - Nice to know what not to do =] – Graham Charlesby Dec 31 '12 at 17:00

2 Answers2

3
FirstClass(ThirdClass ());

What is this supposed to do?

If the type ThirdClass has been declared then it declares a constructor that takes the address of a function as its argument, that's not what you wanted, right? ThirdClass () is the type of a function that takes no arguments and returns a ThirdClass, so your constructor argument is (the address of) a function of that type.

If ThirdClass hasn't been declared (and the error you're getting implies it hasn't been) then it is equivalent to:

FirstClass ThirdClass();

i.e. a (non-constructor) function called ThirdClass which returns a FirstClass object.

You probably wanted it to be a constructor taking a ThirdClass object as the argument, which would be:

FirstClass(ThirdClass);

Or to avoid copying the argument (which is usually what you want):

FirstClass(const ThirdClass&);

Similarly for your Init function.

The errors saying ThirdClass is not a type name indicate the type hasn't been declared. We can only guess because you didn't show a complete, self-contained example (no cookie for you) but you probably have #include "FirstClass.h" in your ThirdClass.h header, which causes circular reference and only one of the files is processed correctly.

See these questions (and their answers) for more:
cyclic dependency between header files
C++ cyclical header dependency
C++ error: 'Line2' has not been declared

Community
  • 1
  • 1
Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
2

I guess, your constructor and Init() should be

FirstClass(const ThirdClass &rhs);
...
void Init (const ThirdClass &rhs);

Furthermore, you should consider adding include guards.

Olaf Dietsche
  • 72,253
  • 8
  • 102
  • 198