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
Related
class A{
public:
void printer(){
B obj;
obj.private_data = 10; // <- fails, says member inaccessible
}
}
class B{
friend void A::printer();
private:
int private_data;
}
is it possible for printer function to access private members of class B? i tried to pass an obj of B as arg to printer but it still failed
Class A doesn't know about B to use it. Hence, postpone the definition of the function printer() until you define B, and if you need an instance of B to be a member var in A then make a forward declaration for B to declare a B* in A.
Hence, use something like what follows:
class A {
public:
void printer();
};
class B {
friend void A::printer();
private:
int private_data;
};
void A::printer() {
B obj;
obj.private_data = 10; // <- No longer fails
std::cout << obj.private_data;
}
int main() {
A a;
a.printer();
}
Demo
Why Friend Function cannot access private members of a class?
They can, but you may need to split the definition of the class up a bit.
Imaginary files added:
Define A (file a.hpp):
class A {
public:
void printer();
};
Define B (file b.hpp):
#include "a.hpp" // B must see the definition of A to befriend a member function
class B {
friend void A::printer();
private:
int private_data;
};
Define A's member function (file a.cpp):
void A::printer() {
B obj;
obj.private_data = 10;
}
To access B, you first need to define it. Thus, you can just declare the method printer and define it after you have defined the class B.
class A {
public:
void printer();
};
class B {
private:
friend class A;
int private_data;
};
void A::printer() {
B obj;
obj.private_data = 10;
}
Note, you probably want to move your methods out of your class definition anyways and into a separate .cpp file. Methods defined inside the class are implicitly marked as inline which might not be what you expect.
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;
}
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();
}
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;
};
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) {};
};