EDIT: this has been marked as a duplicate. I believe there is a distinction between Q: what can I use to solve my problem, A: this thing ~and~ Q: what is this thing? A: big huge in depth answer. I'm not sure what the official ruling on this is though.
I have two classes which both need to know about each other
// Creator.h
#pragma once
#include "Creation.h"
class Creator {
Creator() {
myThing = new Creation(*this);
}
int age = 42;
Creation myThing*;
}
.
// Creation.h
#pragma once
#include "Creator.h"
class Creation {
Creation(Creator &whoMadeMe) {
std::cout << whoMadeMe.age;
}
}
The issue is that whenever I do something like this, I'll get an error that one or the other does not yet exist. In this case, Creation(Creator &whoMadeMe)
would give an error Creator does not exist
due to the Creation class not being ready to reference.
Up until this point, I've always found a way to have only one class know about the other, or perhaps use some parent class to avoid referencing the class which references back. But I'm at an impasse here where I need both of these classes to know each other and their properties, and I need one to create the other.
So, in scenarios like this, where one must pass the this
pointer to a constructor, how can that be done without creating a circular reference, or having to lose/recast the typing?
Also, if losing/recasting the typing is the best solution, please let me know. I've always been told to avoid it and am assuming it is not the solution as a result.
You need to separate declaration (in .h files) and implementation (in .cpp files). Then use forward declaration in header files to prevent circular reference. In implémentation files you can use includes.
It will fix your issue but also optimize your compilation.
Check What are forward declarations in C++? and Separating class code into a header and cpp file.
As far as you do not use a class but only declare attributes or parameters as pointers or references to the class you can use class Creator;
rather than #include "Creator.h"
Not sure this is best practice, but you can use template
to solve this
#include <iostream>
class Creation
{
public:
template<typename Creator> // type concept of Creater
Creation(Creator &whoMadeMe)
{
std::cout << whoMadeMe.age;
}
};
class Creator
{
public:
Creator()
{
myThing = new Creation(*this);
}
int age = 42;
Creation * myThing = nullptr;
};
godbolt link: https://godbolt.org/z/ILbFpS
BTW, use new
carefully. Or use smart pointers to make life easier.
来源:https://stackoverflow.com/questions/53796867/how-can-i-pass-this-to-a-constructor-without-circular-references-or-losing-ty