Errors using forward declaration in c++ - c++

I am trying to write a simple program in c++ where I have 2 classes, and both can access functions from each other. This is a simplification of what I am actually trying to do in the end, which is to create a game with board and piece classes. I was able to do this in java, but I am now running into problems trying to do the same in c++. My code is as follows:
#include <iostream>
class B;
class A {
public:
void sync(B obj){
b = obj;
}
void print(){
std::cout << "Hello from class A" << std::endl;
}
void printBoth(){
std::cout << "Hello from class A" << std::endl;
b.print();
}
private:
B b;
};
class B {
public:
B(A obj){
a = obj;
}
void print(){
std::cout << "Hello from class B" << std::endl;
}
void printBoth(){
std::cout << "Hello from class B" << std::endl;
a.print();
}
private:
A a;
};
int main(){
A a;
B b(a);
a.sync(b);
a.printBoth();
std::cout << std::endl;
b.printBoth();
return 0;
}
When I try to compile this with g++ example.cpp, I receive 5 errors:
example.cpp:20:5: error: field ‘b’ has incomplete type
B b;
^
example.cpp: In member function ‘void A::sync(B)’:
example.cpp:7:8: error: ‘obj’ has incomplete type
void sync(B obj){
^
example.cpp:3:7: error: forward declaration of ‘class B’
class B;
^
example.cpp:8:4: error: ‘b’ was not declared in this scope
b = obj;
^
example.cpp: In member function ‘void A::printBoth()’:
example.cpp:17:4: error: ‘b’ was not declared in this scope
b.print();
^
I have never used forward declaration with classes, so I apologize if I am missing something glaringly obvious. Any help is appreciated, and I thank you in advance.

There are two problems with your code.
Let's take the first problem.
Here's an example of two classes with methods that call each other. Pretty meaningless, and results in an infinite loop, but this demonstrates the general principles of forward declarations, and you can use this as a template to fix the code you've shown.
class A {
public:
void foo();
};
class B {
public:
void foo();
};
void A::foo()
{
B b;
b.foo();
}
void B::foo()
{
A a;
a.foo();
};
Now, the second problem with your code:
As written, your class A contains an instance of class B, which contains an instance of class A, which contains an instance of class A, which contains an instance of class B, all the way until the universe implodes in one massive black hole. Suffice to say, this is not going to compile.
C++ objects are fundamentally different from Java objects. They work in completely different ways. You can do this in Java because the dirty little secret is that all objects in Java are really a mirage, they are really reference-counted pointers to the actual objects. In C++, the closest equivalent of this would be to declare a std::shared_ptr to the object:
#include <memory>
class A;
class B;
class A {
// ...
private:
std::shared_ptr<B> b;
};
class B {
// ...
private:
std:shared_ptr<A> a;
};
And this would be the second problem with your shown code. In general, you need to pretty much forget everything you know about Java objects, when learning C++ objects. They are fundamentally different, and trying to consistently draw analogies between what you already know about Java objects, and C++ objects, will only lead to confusion.

You can always try to redesign i.e:
#include <iostream>
#include "A.hpp"
int main(){
A a;
B b(a);
a.sync(b);
a.printBoth();
std::cout << std::endl;
b.printBoth();
return 0;
}
B.hpp:
class A;
class B {
public:
B() {}
B(A obj);
void print();
void printBoth();
private:
A* a;
};
B.cpp:
#include <iostream>
#include "A.hpp"
B::B(A obj){
a = new A(obj);
}
void B::print(){
std::cout << "Hello from class B" << std::endl;
}
void B::printBoth(){
std::cout << "Hello from class B" << std::endl;
a->print();
}
A.hpp:
#include "B.hpp"
class A {
public:
void sync(B obj);
void print();
void printBoth();
private:
B b;
};
A.cpp:
#include <iostream>
#include "A.hpp"
void A::sync(B obj){
b = obj;
}
void A::print(){
std::cout << "Hello from class A" << std::endl;
}
void A::printBoth(){
std::cout << "Hello from class A" << std::endl;
b.print();
}

Related

C++ Managing pointers to functions inside another class

I'm trying to write a program that calls for a function stored inside a class whose implementation is defined by another object instance.
Let me clarify this better: I would like to create an object A and call for its functions (like an abstract object), but the body of this functions should be defined by either an instance of class B or class C.
I know abstract classes exist in C++ and that i could just call the derived objects, but my goal is to call for object A methods without caring (or knowing in advance) whether an instance of object B or C was previously created.
I tried to use pointers to functions, unfortunately with no results. My code was something like this
Class A:
class A {
public:
static void (*someFunction)();
};
Class B:
class B {
public:
B(){
A::someFunction = someFunction;
}
private:
void someFunction(){
std::cout << "some function" << std::endl;
}
};
Main code:
B b;
A::someFunction();
What am I doing wrong or could be done in a more simple and elegant way? Sorry for the poor explaination and thank you in advance for your help.
Polymorphism exists for just this type of situation, eg:
class A {
public:
virtual ~A() = default;
virtual void someFunction() = 0;
};
class B : public A {
public:
void someFunction() override {
std::cout << "some function" << std::endl;
}
};
class C : public A /* or B*/ {
public:
void someFunction() override {
std::cout << "some other function" << std::endl;
}
};
void doIt(A &a) {
a.someFunction();
}
B b;
doIt(b);
C c;
doIt(c);
Online Demo
But, if that is not what you want, then consider having A use std::function instead of a raw function pointer. Then B and C can assign whatever they want to A::someFunction using lambdas or std::bind(), eg:
A.h:
#include <functional>
class A {
public:
static std::function<void()> someFunction;
};
A.cpp:
#include "A.h"
std::function<void()> A::someFunction;
B.h:
#include "A.h"
class B {
public:
B(){
A::someFunction = [this](){ someFunction(); };
or:
A::someFunction = std::bind(&B::someFunction, this);
}
private:
void someFunction(){
std::cout << "some function" << std::endl;
}
};
C.h:
#include "A.h"
class C {
public:
C(){
A::someFunction = [this](){ someFunction(); };
or:
A::someFunction = std::bind(&C::someFunction, this);
}
private:
void someFunction(){
std::cout << "some other function" << std::endl;
}
};
#include "A.h"
#include "B.h"
#include "C.h"
B b;
A::someFunction();
C c;
A::someFunction();
Online Demo

Inheritance c++ upcasting

I have a little problem with this code :
#include <iostream>
class A {
public:
void PrintA() {
std::cout << "A";
}
};
class B : public A {
public:
void PrintB() {
std::cout << "B";
}
};
int main() {
A a;
a.PrintA();
B b;
b.PrintA();
b.PrintB();
system("PAUSE");
}
Can you tell me if there exist a way to define in A class an object B and use it's methods something like :
class A {
public:
void PrintA() {
std::cout << "A";
}
B bclass;
};
And use in main function something like :
int main() {
A a;
a.bclass->PrintB();
system("PAUSE");
}
The question you need to ask yourself
How does the compiler figure out the size of A
Well - It needs to figure out the size of B
But B has an A in it.
You can go around that loop forever
So you cannot do it.
So use a pointer and forward declaration
Generally functions definition is placed in cpp files and class definition in h or hpp files.
In cpp files you include both hpp with both classes.
Each function defined in cpp have see definition of both classes and may create new one of them.
But in declaration you may only use pointer or reference to object of that class.
== a.hpp ==
#pragma once
class B;
class A {
public:
void PrintA();
B* b;
};
== b.hpp ==
#pragma once
#include "a.hpp"
class B : public A {
public:
void PrintB();
A* a;
};
== a.cpp ==
#include "a.hpp"
#include "b.hpp"
void A::PrintA() {
b = new B();
std::cout << "A";
}
== b.cpp ==
#include "a.hpp"
#include "b.hpp"
void B::PrintB() {
a = new A();
std::cout << "A";
}
And main:
int main() {
A a;
a.PrintA();
a.b->PrintB();
B b;
b.PrintA();
b.PrintB();
system("PAUSE");
}
Worked example available at this link all in one file.
There one else link where seems Visual Studio compiler used.
Just for a sample, you can point to a B instance from an A instance like below, with a pointer:
class A {
public:
void PrintA() {
std::cout << "A";
}
std::unique_ptr<B> bclass;
};
A a;
A.bclass=new B;
A.bclass->PrintB();
The unique pointer will manage memory deallocation.

member function pointer conversion

#include <iostream>
using namespace std;
class A {
};
typedef void (A::*funA)(int);
class B : public A {
public:
void m(int) {std::cout << "mm" << std::endl; }
void n(int) { std::cout << "nn"<<std::endl; }
};
typedef void (B::*funB)(int);
class C : public B {
public:
void g(int) {std::cout << "gg" << std::endl; }
void h(int) { std::cout << "hh"<<std::endl; }
};
typedef void (C::*funC)(int);
int main() {
funB f = static_cast<funB>(&C::m);
A* pa = new A;
(pa->*(static_cast<funA>(f)))(2);
return 0;
}
gcc compile and output "mm".
But why can this work? Class A in fact don't define any function.
It seems the class can use its base class or derived class function by this way, even though it doesn't define them.
Since A doesn't contain the member that f refers to, the behaviour is undefined.
The probable reason why it works anyway is that the function B::m doesn't touch the this pointer, so it doesn't "notice" when it's called on an object of the wrong type. Also, A and B are not polymorphic, so dereferencing the pointer-to-member and calling doesn't require examining any vptr.

How to pass instance of one class to another via constructor

I have a simple question. How would you go about passing an instance of a class to a constructor of another class in c++? I have experience in C, however I am struggling with the syntax of c++.
For example say I have Class A and want to pass and Instance of it to Class B.
A.h
class A {
A();
virtual ~A();
public:
B *newb;
}
A.cpp
A::A() {
newb = new B(this);
}
b.h
class B {
B(A *instanceA);
virtual ~B();
}
Could someone please provide me with a simple example? It would be much appreciated.
EDIT: I tried this concept with my current code, but kept getting errors. Sorry I wanted to make sure that I used the right principle. This is a snippet of the code that I am currently working on.
//SentencSelection.h
class SentenceSelection
{
public:
SentenceSelection(TestBenchGui *test);
virtual ~SentenceSelection();
//do stuff
};
//SentencSelection.cpp
#include <iostream>
#include "SentenceSelection.h"
using namespace std;
SentenceSelection::SentenceSelection(TestBenchGui *test)
{
//do stuff
}
SentenceSelection::~SentenceSelection()
{
}
//TestBenchGui.h
#include "SentenceSelection.h"
class TestBenchGui
{
public:
TestBenchGui();
virtual ~TestBenchGui();
private:
SentenceSelection *selection;
};
//TestBenchGui.cpp
#include "TestBenchGui.h"
#include "SentenceSelection.h"
using namespace std;
TestBenchGui::TestBenchGui()
{
selection = new SentenceSelection(this);
}
TestBenchGui::~TestBenchGui()
{
}
When I compile this in eclipse I get the follwing error "expected constructor, destructor, or type conversion before ‘(’ token" for the line - "SentenceSelection::SentenceSelection(TestBenchGui test)" in SentenceSelection.h.
I believe the code you have does pretty much what you are asking, but there are a couple of syntax errors that are probably holding you back from compilation (and thus leading to some confusion). Below is code that I put in a single file (main.cpp) and was able to compile. I added some comments and print statements to highlight the difference between DECLARATIONS and IMPLEMENTATIONS:
#include <iostream>
using std::cout;
using std::endl;
// forward declaration so we can refer to it in A
class B;
// define A's interface
class A {
public:
// member variables
B *newb;
// constructor declaration
A();
// destructor declaration
virtual ~A();
}; // note the semicolon that ends the definition of A as a class
class B {
public:
// B constructor implementation
B(A *instanceA){cout << "I am creating a B with a pointer to an A at " << instanceA << endl;}
// B destructor implementation
virtual ~B(){cout << "Destructor of B" << endl;}
}; // note the semicolon that ends the definition of B as a class
// A constructor implementation
A::A(){
cout << "I am creating an A at " << this << ", allocating a B on the heap..." << endl;
newb = new B(this);
}
// A destructor implementation
A::~A(){
cout << "Destructor of A, deleting my B...." << endl;
delete newb;
}
int main(){
A an_a;
}
Output for my system from running the above program:
I am creating an A at 0x7fff64884ba0, allocating a B on the heap...
I am creating a B with a pointer to an A at 0x7fff64884ba0
Destructor of A, deleting my B....
Destructor of B
Hope this helps.
For example say I have Class A and want to pass and Instance of it to Class B.
If you intend to pass a pointer to the instance, then you have already figured it out. The constructor that you declared takes an A* as an argument:
B(A *instanceA);
#include <iostream>
using namespace std;
class B
{
public:
B(){};
int x;
~B(){};
};
class A
{
public:
A(){}; // default constructor
A(B& b) // constructor taking B
{
y = b.x;
}
~A(){};
int y;
};
int main()
{
B myB;
myB.x = 69;
A myA(myB);
cout << myA.y << endl;
return 0;
}
I answer strictly your question:
If you want to pass a instance on a constructor best practice is pass as a reference:
class CA{
CB &b;
public:
CA( CB &p_b) : b(p_b){};
virtual ~CA();
};
But in your example you have a classes with cross references that is another case

Data access from a member function of different classes in C++

I am confused how to implement data member access from a different class.
I have three classes in three different header files.
A.h
#include "B.h"
#include "C.h"
class A{
B *b;
friend void dataaccess_b_from_class_A(int a);
}
B.h
class B{
}
C.h
class C{
void dataaccess_b_from_class_A(int a);
}
void C::dataaccess_b_from_class_A(int a)
{
b = new B(); //I got error as symbol b could not be resolved.
}
I like dataaccess_b_from_class_A() method from class C access data B *b from Class A.
I put friend function inside class A, but I got error as symbol b could not be resolved.How can I implement it?
EDIT1:
According to the discussion 'gmas80',
what I did was
class B; // forward declaration
class A{
public:
A(){};
private:
static B* b; // since in the dataaccess_to_class_A you are using new
friend class C; // this make b and dataaccess_from_class_C accessible
};
class B{
public:
B(){ cout << "B" << endl; };
// add content
};
class C{
public: // you need this keyword if you want to call this function from outside
void dataaccess_to_class_A(A a);
};
void C::dataaccess_to_class_A(A a)
{
A::b = new B(); //Error as undefined reference to class A::b
cout << "C" << endl; // test if called
}
If I don't include static, I got b could not be resolved.
If I include static, I got undefined reference.
Thanks
You have included so many mistakes in a so small piece of code! why don't you start simpler? Here a modified single-file version of your code that compiles:
#include <iostream>
using namespace std;
class B; // forward declaration
class A{
public:
A(){};
private:
B* b; // since in the dataaccess_to_class_A you are using new
void dataaccess_from_class_C(){ cout << "A" << endl; }; // test if called
friend class C; // this make b and dataaccess_from_class_C accessible
};
class B{
public:
B(){ cout << "B" << endl; };
// add content
};
class C{
public: // you need this keyword if you want to call this function from outside
void dataaccess_to_class_A(A a);
};
void C::dataaccess_to_class_A(A a)
{
a.b = new B(); // this is a potentially memory leak if you will not delete in somehow
a.dataaccess_from_class_C();
cout << "C" << endl; // test if called
}
// it is better if you post runnable code
int main() {
C c;
A a;
c.dataaccess_to_class_A(a);
}
AFTER EDIT1
Now you can start to move the class in a header file, but you need to add guardians to avoid multiple definitions..
a.h
#ifndef H_GUARDIAN_A
#define H_GUARDIAN_A
#include <iostream>
using namespace std;
class B; // forward declaration
class A
{
public:
A()
{};
private:
B* b; // since in the dataaccess_to_class_A you are using new
void dataaccess_from_class_C()
{
cout << "A" << endl;
}; // test if called
friend class C; // this make b and dataaccess_from_class_C accessible
};
class B
{
public:
B()
{
cout << "B" << endl;
};
// add content
};
class C
{
public: // you need this keyword if you want to call this function from outside
void dataaccess_to_class_A( A a );
};
void C::dataaccess_to_class_A( A a )
{
a.b = new B(); // this is a potentially memory leak if you will not delete in somehow
a.dataaccess_from_class_C();
cout << "C" << endl; // test if called
}
#endif
main.cpp
#include "a.h"
// it is better if you post runnable code
int main()
{
C c;
A a;
c.dataaccess_to_class_A( a );
}
Does it make sense for you? I simple moved the class declarations in another file that is included..
EDIT2
Now we split the class definitions in three different headers..
a.h
#ifndef H_GUARDIAN_A
#define H_GUARDIAN_A
#include <iostream>
using namespace std;
class B;
class A
{
public:
A(): b(NULL){}; // initialize to NULL the b pointer
~A(); // new entry: destructor to eventually delete b (only member function declaration)
private:
B* b; // since in the dataaccess_to_class_A you are using new
void dataaccess_from_class_C()
{
cout << "A" << endl; // test if called
};
friend class C; // this make b and dataaccess_from_class_C accessible
};
#endif
a.cpp // new entry! it avoids circular dependency.. the destructor is defined here
#include "a.h"
#include "b.h"
A::~A() // destructor that eventually clean memory for b
{
if( b ) delete b;
}
b.h
#ifndef H_GUARDIAN_B
#define H_GUARDIAN_B
#include "a.h"
class B
{
public:
B()
{
cout << "B" << endl;
};
// add content
};
#endif
c.h
#ifndef H_GUARDIAN_C
#define H_GUARDIAN_C
#include "b.h"
class C
{
public: // you need this keyword if you want to call this function from outside
void dataaccess_to_class_A( A a );
};
void C::dataaccess_to_class_A( A a )
{
a.b = new B(); // this is a potentially memory leak if you will not delete in somehow
a.dataaccess_from_class_C();
cout << "C" << endl; // test if called
}
#endif
main.cpp
#include "c.h"
// it is better if you post runnable code
int main()
{
C c;
A a;
c.dataaccess_to_class_A( a );
}
add
include "B.h"
in the beginning if the C.h
and define the type of b
B b( new B() );
also, specify the fully qualified method in your freind declaration:
friend void C::dataaccess_b_from_class_A(int a);
include C.h into A.h,
and do not forget include guards in each header
Another point. Why are you defining C::dataaccess_b_from_class_A in the header? I would suggest to do it in a separate file. Say, "C.cpp".