again on forward declaration

A

Andrea Crotti

I fell into the forward declaration trap, so I made a small example to
be sure I understood.

Suppose I have
#include <iostream>
#include "A.h"

void A::nothing()
{
std::cout << b->x;
}

int main(int argc, char *argv[])
{

return 0;
}

#ifndef B_H
#define B_H

class B
{
public:
int x;
};

#endif /* B_H */

#ifndef B_H
#define B_H

class B
{
public:
int x;
};

#endif /* B_H */

In A.h I forward declare the class B, but since I have to really use
the pointer it doesn't work.
(incomplete type).

So I guess in those cases I can only include the class that defines
that type (which I wanted to avoid), right?
 
A

Andrea Crotti

Actually it's even worse, because this would be my real situation

#ifndef B_H
#define B_H

// if I don't use a pointer below I'm in trouble
class A;

class B
{
private:
A member;

public:
int x;
};

#endif /* B_H */

#ifndef A_H
#define A_H

#include "B.h"

class A
{
private:
B *b;

public:
void nothing();
};

#endif /* A_H */


With the member "A member" it doesn't work, it only works if it's also
a pointer
"A *member".
Maybe I should solve it differently, because I guess there's no simple
way to do what I wanted...
 
V

Victor Bazarov

Actually it's even worse, because this would be my real situation

#ifndef B_H
#define B_H

// if I don't use a pointer below I'm in trouble
class A;

Instead of forward-declaring 'A' (which doesn't work as you have found
out already), #include the header where the definition of 'B' is.
class B
{
private:
A member;

public:
int x;
};

#endif /* B_H */

#ifndef A_H
#define A_H

#include "B.h"

Instead of #include, use a forward-declaration here, you don't need to
know what's inside 'B' to declare a member 'b' of the type 'B*'.
class A
{
private:
B *b;

public:
void nothing();
};

#endif /* A_H */


With the member "A member" it doesn't work, it only works if it's also
a pointer
"A *member".
Maybe I should solve it differently, because I guess there's no simple
way to do what I wanted...

Yes, there is.

V
 
A

Andrea Crotti

Instead of #include, use a forward-declaration here, you don't need to
know what's inside 'B' to declare a member 'b' of the type 'B*'.

Ah yes sure with a pointer it works, with "B b" it doesn't...
But it's ok, I think I will just use std::auto_ptr and it'll be
perfectly fine.
 
A

Andrea Crotti

Ok I thought I got it, but still no luck, why does this below doesn't
work?
I compile with "g++ A.cpp B.cpp" (does the order matter?)
but no luck, still

B.cpp: In constructor ‘B::B()’:
B.cpp:5: error: invalid use of incomplete type ‘struct A’
B.h:7: error: forward declaration of ‘struct A’

#ifndef B_H
#define B_H

#include <memory>

// if I don't use a pointer below I'm in trouble
class A;

class B
{
private:
A *member;

public:
int x;
B();
};

#endif /* B_H */

#ifndef A_H
#define A_H

#include "B.h"

class A
{
private:
B *b;

public:
void nothing();
};

#endif /* A_H */
#include "B.h"

B::B()
{
member = new A();
}

#include <iostream>
#include "A.h"

void A::nothing()
{
std::cout << b->x;
}

int main(int argc, char *argv[])
{
A a;
a.nothing();
return 0;
}
 
V

Victor Bazarov

Ok I thought I got it, but still no luck, why does this below doesn't
work?

Because you haven't followed all my suggestions.
I compile with "g++ A.cpp B.cpp" (does the order matter?)

AFAIK, no, order does not matter. The resulting executable's name will
depend on what file you give it first, but you haven't got that far yet.
but no luck, still

B.cpp: In constructor ‘B::B()’:
B.cpp:5: error: invalid use of incomplete type ‘struct A’
B.h:7: error: forward declaration of ‘struct A’

#ifndef B_H
#define B_H

#include<memory>

// if I don't use a pointer below I'm in trouble
class A;

Don't forward-declare, #include
class B
{
private:
A *member;

Didn't you need 'A member;' here? Whatever...
public:
int x;
B();
};

#endif /* B_H */

#ifndef A_H
#define A_H

#include "B.h"

There is no need to include 'B' here is you never use any members of 'B'
in your header.
class A
{
private:
B *b;

public:
void nothing();
};

#endif /* A_H */

Below starts another file, yes? You need to indicate that!
#include "B.h"

B::B()
{
member = new A();
}

Again new file, no? Tell us that! What are we, mind readers? Why do I
have to guess? Jeez...
#include<iostream>
#include "A.h"

void A::nothing()
{
std::cout<< b->x;

You need to give the compiler the *definition* of class 'B' to use its
members. You forgot to #include "B.h" in this TU.
}

int main(int argc, char *argv[])

If you're not using 'argc' and 'argv', why do you write them? Just use

int main()
{
A a;
a.nothing();
return 0;
}

Try to pay attention.

V
 
A

Andrea Crotti

Thanks you all now it works :)
What I wanted to avoid was to include the "A.h" in the .cpp,
because I felt it was logically wrong...
But well of course there are no other ways, the compiler
can't imagine how the class really is
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top