C++ - 2 classes 1 file - c++

Suppose I want something of this sort, in one .cpp source file:
class A {
public:
void doSomething(B *b) {};
};
class B {
public:
void doSomething(A *a) {};
};
Is there anyway of doing this without splitting it into two separate files, and without receiving a compiler error (syntax error on doSomething(B *b))

put at the first line:
class B;

If I remember well, you can 'pre-declare' your class B.
class B; // predeclaration of class B
class A
{
public:
void doSomething(B* b);
}
class B
{
public
void doSomething(A* a) {}
}
public void A::doSomething(B* b) {}
Then, your class 'A' knows that a class 'B' will exists, although it hasn't been really defined yet.
Forward declaration is indeed the correct term, as mentionned by Evan Teran in the comments.

forward declare one class before other with
class B;
or
class A;
But still you won't be able to implement
void doSomething(B *b)
using only forward declaration of B. So you have to put definition of doSomething below full class A declaration

Yes. You need a forward declaration:
class B; // add this line before A's declaration
class A {
public:
void doSomething(B *b) {};
};
class B {
public:
void doSomething(A *a) {};
};

The C++ FAQ Lite answers this question and others. I'd seriously considering reading that thing end to end, or getting the book and doing the same.

You can try a forward declaration like
class B;
class A {
void Method( B* );
};
class B{
};
but you will only be able to declare pointer and reference variables for B then. If you want more (like a method that dereferences B* variable) you can provide a declaration only and define methods later in the same file - at the point where both classes declaration is already available.

You need to forward declare B.
class B;
class A
{
public:
void doSomething(B *b) {}
};
class B
{
public:
void doSomething(A *a) {}
};
(And BTW, you don't need the semi-colons after the member function curly braces. :) )

Add another declaration of B before A:
class B;
class A {
public:
void doSomething(B *b) {};
};
class B {
public:
void doSomething(A *a) {};
};

Related

Cyclic dependency involving global objects C++

So, I'm in this situation right now. I have two classes A and B. The B is subclass of A and there's also a global object of the B class which is initialized in the main. A function of the A class uses that global object and calls its functions. In what order do I have to write the declarations in order for the compiler to read everything?
I keep getting the same errors whatever I try. Namely:
- (x) does not name a type
- invalid use of incomplete type (x)
- forward declaration of (x)
Code example:
class B;
B* B_GLOBAL;
class A{
public:
void A_function(){
B_GLOBAL->B_function();
}
private:
};
class B : public A{
public:
void B_function();
private:
};
int main(void){
B_GLOBAL = new B;
return 0;
}
Move the definition of A_function below the declaration of B:
class B;
B* B_GLOBAL;
class A{
public:
void A_function();
private:
};
class B : public A{
public:
void B_function();
private:
};
void A::A_function(){
B_GLOBAL->B_function();
}
int main(void){
B_GLOBAL = new B;
return 0;
}

C++ header file referencing a struct defined below

What is considered the best practice for handling this situation?
class A {
private:
std::vector<B> derp;
public:
struct B { ... };
void foo(B b);
}
(The problem is that this code would say "error: use of undeclared identifier 'B'"
I think I could solve the problem by doing something like
class A {
public:
struct B { ... };
void foo(B b);
private:
std::vector<B> derp;
}
But that seems strange and not like the proper solution. Also as a side note, if I were to write that should I write it like this?
struct A {
struct B { ... };
void foo(B b);
private:
std::vector<B> derp;
}
You could use a forward declaration of B before declaring derp if you don't want to move the definition of B before declaring derp.
class A {
public:
struct B;
private:
std::vector<B> derp;
public:
struct B { ... };
void foo(B b);
};
However, from a physical layout perspective, the public section of a class shoud be before its private section. You want the public section to be seen by a user first.
Given that, I think it'll be better to use:
class A {
public:
struct B { ... };
void foo(B b);
private:
std::vector<B> derp;
};
That solves the problem of B not being declared/defined before the declaration of the member variable derp. It also puts the public section ahead of the private section.
Just like variables, you can forward-declare classes and structures. For example, in your case you can do the following:
class A {
public:
struct B;
private:
std::vector<B> derp;
public:
struct B { ... };
void foo( B b );
};
Keep in mind if you forward-declare a class or structure within a class, you need to declare it with the same access level (private/protected/public) as you define it later.

C++ classes with members referencing each other and being used

I have 2 c++ classes with members referencing each other. I am calling members of the referenced classes, so I can't use forward declarations, because I get the error "pointer to incomplete class type is not allowed"
class A {
B* b;
void foo() {
b->do_something();
}
};
class B {
A* a;
void bar() {
a->do_something_else();
}
};
Is there any way to get the includes to work here?
There is already a ticket open by a similar name but I can't use the solution there.
Just separate the definitions from the declarations:
class B;
class A {
public:
void foo();
void do_something_else(){}
private:
B* b;
};
class B {
public:
void bar();
void do_something(){}
private:
A* a;
};
//now B has a complete type, so this is fine
void A::foo() {
b->do_something();
}
//ditto
void B::bar() {
a->do_something_else();
}
You can use the prototype definitions in a header file. And the logical body in a cpp file.
After doing this you can use the forward declaration in the header( class B, class A)
Example: #TartanLlama

error: member access into incomplete type : forward declaration of

I have two classes in the same .cpp file:
// forward
class B;
class A {
void doSomething(B * b) {
b->add();
}
};
class B {
void add() {
...
}
};
The forward does not work, I cannot compile.
I get this error:
error: member access into incomplete type 'B'
note: forward declaration of 'B'
I'm using clang compiler (clang-500.2.79).
I don't want to use multiple files (.cpp and .hh), I'd like to code just on one .cpp.
I cannot write the class B before the class A.
Do you have any idea of how to resolve my problem ?
Move doSomething definition outside of its class declaration and after B and also make add accessible to A by public-ing it or friend-ing it.
class B;
class A
{
void doSomething(B * b);
};
class B
{
public:
void add() {}
};
void A::doSomething(B * b)
{
b->add();
}
You must have the definition of class B before you use the class. How else would the compiler otherwise know that there exists such a function as B::add?
Either define class B before class A, or move the body of A::doSomething to after class B have been defined, like
class B;
class A
{
B* b;
void doSomething();
};
class B
{
A* a;
void add() {}
};
void A::doSomething()
{
b->add();
}

How do I access a private constructor in a separate class?

I'm writing a library in C++. I have two classes in my library, A and B. I want to hide the A() constructor from any code that references my library. I also want class B to be able to call the A() constructor.
I come from a C# background and remember little of my C++. In C#, I would simply declare the A() constructor as internal. I've read that the closest way to do this in C++ is a combination of friend declarations and forward-declarations. How do I do this? Here are my three files below:
A.h:
#pragma once
class A
{
private:
A();
};
B.h
#pragma once
class A;
class B
{
public:
A createA();
};
B.cpp:
#include "A.h"
#include "B.h"
A B::createA()
{
A result; //cannot access private member declare in class 'A'
return result;
}
I've tried adding this to A.h:
public: friend A createA();
I've instead tried adding this to A.h with a corresponding forward declaration:
public: friend A B::createA();
I've instead tried adding and extern class B; to A.h and making B a class like this:
public: friend class B;
I'm at a loss.
I think this might be easier if I have the B::createA() function return a pointer to an A object rather than an A object directly, but that won't do in my case. I am emulating a closed API and the API call returns an A object rather than a pointer.
You probably just need to drop the "extern" from your third attempt to turn it into a proper forward-declaration. Try:
A.h:
#pragma once
class B;
class A
{
friend class B;
private:
A();
};
You don't need the external keyword. Make it simple:
// In A.h
class B; // Forward declaration
class A
{
friend class B; // Make all the class B friend
A();
};
// In B.h
class B
{
public:
A createA() {}
};
Live Example.
Unless absolutely necessary, you should have A construct itself (or have a factory that creates A). If you really want B to do it:
class B; // foward declared
class A
{
private:
A() {}
friend class B;
};
class B
{
public:
A CreateA()
{
A a;
return a;
}
};
int main()
{
B b;
A a = b.CreateA();
return 0;
}
Note: You must forward declare B before declaring it a friend in A.
If you want just the function as a friend:
class A;
class B
{
public:
A CreateA();
};
class A
{
private:
A() {}
friend class A B::CreateA();
};
A B::CreateA()
{
A a;
return a;
}
int main()
{
B b;
A a = b.CreateA();
return 0;
}
You can make B a friend of A:
class A
{
private:
A();
friend class B;
};