Mutual class instances in C ++

What is the problem with this code? Here we have two files: classA.h and classB.h

classA.h:

#ifndef _class_a_h_ #define _class_a_h_ #include "classB.h" class B; //???? class A { public: A() { ptr_b = new B(); //???? } virtual ~A() { if(ptr_b) delete ptr_b; //???? num_a = 0; } int num_a; B* ptr_b; //???? }; #endif //_class_a_h_ 

classB.h:

 #ifndef _class_b_h_ #define _class_b_h_ #include "classA.h" class A; //???? class B { public: B() { ptr_a = new A(); //???? num_b = 0; } virtual ~B() { if(ptr_a) delete ptr_a; //???? } int num_b; A* ptr_a; //???? }; #endif //_class_b_h_ 

when I try to compile it, the compiler (g ++) says:

classB.h: In the constructor of B :: B ():

classB.h: 12: error: invalid use of incomplete type 'struct A

classB.h: 6: error: direct declaration 'struct A

classB.h: In destructor 'virtual B :: ~ B ():

classB.h: 16: warning: possible problem detected when the delete statement was called:

classB.h: 16: warning: invalid use of incomplete type 'struct A

classB.h: 6: warning: forward declare 'struct A

classB.h: 16: note: neither the destructor nor the class delete operator will

even if they are declared when the class is defined.

+4
source share
4 answers

You cannot create instances of an incomplete type (the compiler does not know anything about the class!)

You need to move the definitions of your functions (constructor A and B) to a C ++ file, which can include both headers (or to multiple C ++ files, if you agree that you have one class for each file).

As said, your written code has a serious problem: each A creates an instance of B and each B creates an instance of A. You end up with infinite recursion and end up running out of memory.

Two minor nitpicks: you don’t need to check if the pointer is null before calling delete on it (it is safe to delete the null pointer), and you need to change your security features (names starting with underscores in the global namespace are reserved for implementation).

+9
source

EDIT: Read James McNellis first . This is an example code of what you will need to do. But recursion is a bigger moment, and it deserves any enhancements for this particular item, not me :)

You cannot use the built-in functions here, since the full definition for classes A and B is not available if you declare them built-in. Declare them as normal functions, and you will be fine with the announcements that you pointed forward.

classA.h

 #ifndef _class_a_h_ #define _class_a_h_ #include "classB.h" class B; //???? class A { public: A(); virtual ~A(); int num_a; B* ptr_b; }; #endif //_class_a_h_ 

classB.h

 #ifndef _class_b_h_ #define _class_b_h_ #include "classA.h" class B { public: B(); virtual ~B(); int num_b; A* ptr_a; }; #endif //_class_b_h_ 

classes.cpp

 #include "classA.h" #include "classB.h" A::A() { ptr_b = new B(); //???? } A::~A() { if(ptr_b) delete ptr_b; //???? } B::B() { ptr_a = new A; //???? } B::~B() { if(ptr_a) delete ptr_a; //???? } 
+2
source

classB.h: In the constructor of B :: B ():

classB.h: 12: error: misuse incomplete type 'struct A

A not fully defined. You just gave it a prototype ( class A; ).

classB.h: 6: error: forward declaration of 'struct A

classB.h: virtual descriptor B :: ~ B ():

I think this is the same problem. He needs to know how A is defined so that he knows how much memory is freed up.

Rebuild your code to remove the circular dependency. (A creates B, and B creates A ... creates B, creates A, creates B ...)

+1
source

A simple solution is to pull the member function definitions out of line and into classA.cpp and classB.cpp files. Remove the mutual inclusions from the header files and instead insert them into the .cpp files.

An Anywhere A or B class is used more than just by name (that is, apart from just naming its pointer or reference types), a full class declaration must already be provided. With your current inclusion / built-in design, one or the other will not necessarily be completed. By parsing class implementations into .cpp files, you allow declarations to finish gracefully before creating objects of type A or B.

0
source

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


All Articles