How can I pass `this` to a constructor without circular references (or losing type) in c++?

自作多情 提交于 2019-12-23 01:03:26

问题


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.


回答1:


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"




回答2:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!