1

I am trying to have two classes in C++ - class1, class2. I want class2 to contain an instance of class1 and class1 to have a shared_ptr to the class2 – a pointer to the object, in which it is contained. So I have following 4 files:

class2.hpp

#include "class1.hpp"
#include <vector>

class class2 {
    friend class1;
private:
    class1 data;
    std::vector<int> numbers;
public:
    class2();
};

class2.cpp

#include "class2.hpp"

class2::class2() : data(std::shared_ptr<class2>(this)){}

class1.hpp

#include <memory>

class class2;
class class1 {
    std::shared_ptr<class2> ptr;
    class1(std::shared_ptr<class2> ptr);
    void add_item(int i);
};

and class1.cpp

#include "class1.hpp"

class1::class1(std::shared_ptr<class2> ptr) {
    ptr = ptr;
}

void class1::add_item(int i) {
    ptr->add_item(6); //Member access into incomplete type 'std::__1::shared_ptr<class2>::element_type' (aka 'class2')
}

I am getting the error in function add_item. I think that it has something to do with the forward declaration of class2. I found this related topic, but there they dont split the files into header file. error: member access into incomplete type : forward declaration of

If I understand well, I should put the function add_item after definition of class2, but I dont how to solve it, if I want to have the files splitted like this. Is it possible? Please note, that I am trying to solve this in bigger project, this is very simplified.

Thanks is advance for any answer.

Toby V.
  • 425
  • 1
  • 6
  • 15
  • 1
    avoid any `#include` in your .hpp files (use forward declarations). And put your `#include`s in the cpp files – fern17 Nov 18 '21 at 13:40
  • You forgot to include `class2.hpp`, a simple typo. – Sam Varshavchik Nov 18 '21 at 13:41
  • `class1.cpp` should include `class2.hpp`. `class1.hpp` should not include `class2.hpp` – drescherjm Nov 18 '21 at 13:41
  • *"I should put the function add_item after definition of class2"* -- right. Exactly that, but from a flipped perspective. You should put the definition of `class2` before the definition of `add_item`. Then the question should become how do you put (or include) the definition of `class2` at the beginning of `class1.cpp`? – JaMiT Nov 18 '21 at 14:02
  • `std::shared_ptr(this)` is a definite no-no - you can't hand over ownership of `*this` to a `shared_ptr` - it aready has an owner. – molbdnilo Nov 18 '21 at 14:03
  • Might be a bit of information overload for this particular question, but still relevant: [Resolve build errors due to circular dependency amongst classes](https://stackoverflow.com/questions/625799/) – JaMiT Nov 18 '21 at 14:13

2 Answers2

2

Forward declare class1 in class2.hpp and include class2.h in class1.cpp.

class2.hpp:

//#include "class1.hpp"       // REMOVE!
#include <vector>

class class1;                 // ADD
class class2 {
...

class2.cpp:

#include "class2.hpp"
#include "class1.hpp"         // ADD

class1.hpp:

#include <memory>

class class2;                // OK

class1.cpp:

#include "class1.hpp"
#include "class2.hpp"         // ADD

class1::class1(std::shared_ptr<class2> ptr) {
    ptr = ptr;
}
fern17
  • 467
  • 6
  • 20
0

I want class2 to contain an instance of class1 and class1 to have a shared_ptr to the class2 – a pointer to the object, in which it is contained.

No, you should not want that. There is no reason for a sub-object to own (even in shared capacity) their super object.

Furthermore, you cannot access members of an incomplete class. You must define the class first.

eerorika
  • 232,697
  • 12
  • 197
  • 326