C ++: passing this pointer to another class

I am new to C ++, but I have some experience working in Java. During coding, I came across an error that confused me. Here is my code (simplified, but the errors are the same):

hijras:

#pragma once #include "Bh" class A { public: A(); void foo(); void sayHello(); B b; }; 

a.cpp:

 #include "Ah" #include <iostream> A::A() {} void A::foo() { b.bar(this); } void A::sayHello() { std::cout << "Hello" << std::endl; } 

Bh:

 #pragma once #include "Ah" class B { public: B(); void bar(A *a); }; 

B.cpp:

 #include "Bh" B::B(){} void B::bar(A *a) { a->sayHello(); } 

I want to pass an object pointer to a bar function in B so that I can modify and access fields in a string. Oddly enough, I get these errors when I call foo through instance A from another class:

 1>------ Build started: Project: Test, Configuration: Debug Win32 ------ 1> main.cpp 1>d:\stuff\visual studio 2015\projects\test\test\bh(7): error C2061: syntax error: identifier 'A' 1> B.cpp 1>d:\stuff\visual studio 2015\projects\test\test\ah(9): error C3646: 'b': unknown override specifier 1>d:\stuff\visual studio 2015\projects\test\test\ah(9): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 1> A.cpp 1>d:\stuff\visual studio 2015\projects\test\test\bh(7): error C2061: syntax error: identifier 'A' 1>d:\stuff\visual studio 2015\projects\test\test\a.cpp(5): error C2660: 'B::bar': function does not take 1 arguments 1> Generating Code... ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== 

The code works fine if I don't include Ah in Bh and I don't pass anything to the bar function.

I tried to understand what could cause these errors, but I could not solve the problem myself, because I do not understand what causes these errors. What am I doing wrong?

+5
source share
4 answers

In the Ah header file, you have:

 #include "Bh" 

In the Bh header file, you have:

 #include "Ah" 

You have a circle where the definition of A and B depends on each other.


A simple solution is to use a forward declaration in the definition of class B :

  • Replace the line #include "Ah" in the Bh file with class B;
  • Add #include "Ah" to the top of B.cpp

Note that you cannot use forward declaration for class A , the reason is that you have the value B of class B as a member variable of class A :

 #pragma once #include "Bh" class A { public: A(); void foo(); void sayHello(); B b; /// I mean this line here more specifically }; 

The compiler must know the definition of class B in order to determine the correct size for class A. That's why you should put #include "Bh" at the very beginning of Ah .

+2
source

Take a look at B.cpp and see what happens with it turned on:

 #include "Bh" B::B(){} void B::bar(A *a) { a->sayHello(); } 

With Bh inserted instead of turning on, we get:

 #include "Ah" class B { public: B(); void bar(A *a); }; B::B(){} void B::bar(A *a) { a->sayHello(); } 

And then placing Ah instead includes:

 #include "Bh" class A { public: A(); void foo(); void sayHello(); B b; }; class B { public: B(); void bar(A *a); }; B::B(){} void B::bar(A *a) { a->sayHello(); } 

And here we stop because pragma once prevents Bh from re-enabling

We see that in the definition of class A we have B b; , but class B is not yet defined. Kaboom. A cannot be defined without B and B has not yet been defined.

A must have size B to satisfy B b; , therefore, this requires a complete definition of B B needs to know only A , because he needs only a pointer to A to satisfy void bar(A *a); . So that...

hijras

 #pragma once #include "Bh" class A { public: A(); void foo(); void sayHello(); B b; }; 

a.cpp

 #include "Ah" #include <iostream> A::A() {} void A::foo() { b.bar(this); } void A::sayHello() { std::cout << "Hello" << std::endl; } 

Bh

 #pragma once class A; // forward definition of class A class B { public: B(); void bar(A *a); }; 

B.cpp

 #include "Ah" B::B(){} void B::bar(A *a) { a->sayHello(); } 
+2
source

Both headers refer to each other. Only one of them can be evaluated first by the compiler and that it is not possible to resolve the class reference in another header. This is not obvious due to an error, but the "once" # pragma does not include one of the headers as you expect.

If the Bh header file does not need to know the details of the implementation of class A, which is not the case then do not include the Ah file in Bh Instead, change the declaration of the bar () function to look like this:

 bar( class A *a ); 

The compiler can build code from this, which passes a pointer to object A, not knowing anything about what's inside A. It does not need the header Ah

Then include the header file Ah after the header file Bh in B.cpp.

I tested this and it works for me.

+1
source

Make the following changes:

Bh : - Forward declare A

 #pragma once // #include "Ah" class A; //^^^^^^ class B { public: B(); void bar(A *a); }; 

B.cpp : #include "Ah"

 //#include "Bh" #include "Ah" //^^^^^^^^^^^^ B::B(){} void B::bar(A *a) { a->sayHello(); } 

What is it.

0
source

Source: https://habr.com/ru/post/1246193/


All Articles