2

I'm trying to create class Object before defining class. Here is the example.

class A;
class B;

class A{
    public: 
    void fun(B obj){
    }
};
class B{ };
int main(){

    return 0;
}

Here is the Error List:

In member function 'void A::fun(B)':
6   13  [Error] 'obj' has incomplete type
2   7   [Error] forward declaration of 'class B'

Any Solution? I already Searched about it, but failed to solve this.. Thanks in Advance.

pmr
  • 58,701
  • 10
  • 113
  • 156

3 Answers3

3

Provide A::fun()'s definition out-of-line, after B has been fully declared :

#include <iostream>

class A;
class B;

class A {
    public: 
    void fun(B obj);
};

class B{ };

void A::fun(B obj) {}

int main() {
    return 0;
}

The definition wil typically go into a .cpp file, where you'd include B.h to have its complete declaration.

Also, please don't using namespace std;.

Community
  • 1
  • 1
Quentin
  • 62,093
  • 7
  • 131
  • 191
  • Given that B has no dependency on A, but A *does* depend on B, it doesn't make a lot of sense to declare it after A, but that's just a stylistic opinion on my part. If it were me, I'd just move the definition of B to be before A. – stix Aug 17 '15 at 15:16
  • Alternative: Pass the parameter `obj` by reference instead. If it isn't used (like in the example) then the compiler doesn't need the full type, it knows that the size of the reference is the size of a pointer. – Chris Beck Aug 17 '15 at 15:16
  • @ChrisBeck - that still breaks though as soon as you _use_ `obj` inside `A::fun` (with the original definition order). – Useless Aug 17 '15 at 15:17
  • 1
    @stix @ChrisBeck This is obviously a minimal example. There are many situations that would require a specific order of declaration, and the function would also use `B`. By the way, thank you, OP, for the minimal and straight-to-the-point example :) – Quentin Aug 17 '15 at 15:17
  • *sigh* - that was in reply to Chris' pass-by-reference suggestion. I should start using @tags again even though they don't really work in comments. – Useless Aug 17 '15 at 15:21
  • @Useless oh, sorry ! @-tags work fine AFAICT though :) – Quentin Aug 17 '15 at 15:23
  • my comment is moot anyway, it was explained more clearly in Useless' answer – Chris Beck Aug 17 '15 at 15:23
1

At this point:

void fun(B obj) {
}

the compiler needs to know what B is. That is, how big it is, what types its members have, what constructors are defined, etc. Otherwise, it can't generate the code you're asking it to.

You can work around this by:

  1. defining (not declaring) B before A, or
  2. only declare A::fun inline, and move the definition after B has also been defined
  3. pass B obj by pointer or reference - because pointers and references are all the same size, and neither invoke constructors you haven't declared yet, this works, but ... you still can't do anything with the B instance in fun until B has been defined.

    So, the current code will compile, but it will break again if fun does anything more than pointer arithmetic.

Useless
  • 64,155
  • 6
  • 88
  • 132
0

In this function definition,

void fun(B obj){
}

you're telling the compiler that you are going to pass an instance of B on the stack to fun. The compiler therefore needs to know the definition of B so that it knows how much stack space to allocate. At this point in the code, you have only declared that B exists. You have not provided it a definition of B, so it can't know how much memory is required.

[Edited to fix the declaration/definition misstatement]

Rob K
  • 8,757
  • 2
  • 32
  • 36
  • The parameter's definition isn't needed for a function declaration. – juanchopanza Aug 17 '15 at 15:18
  • And please no "on the stack". I'm as guilty of this as anyone, but it's still unhelpful. Besides, the size of B is the least of the compiler's problems, since it doesn't know anything about its copy constructor, destructor, etc. etc. – Useless Aug 17 '15 at 15:20
  • For this guy's level of understanding, 'on the stack' is good enough, and anything else is going to be obfuscating, not clarifying. – Rob K Aug 17 '15 at 15:28