如何解决此回调包含问题?

How can I fix this callback include problem?

我是 C++(和 Whosebug)的新手。我正在努力让一些东西发挥作用,但我遇到了一些 #include 问题。

我想调用我所做的回调 (from here),但我很难做到这一点。

到目前为止,这是我的代码。当我在 someclass.hpp 文件中包含 child.hpp 时(因为 Callback<Child> 需要有关 Child 的信息),它有一个循环包含并且编译器崩溃。

我已经阅读了前向声明(在 someclass.hpp 文件中是 class Child;),在尝试之后我发现这是可行的,但我也阅读了对此的不同意见。

我所有 .hpp 个文件都由 #ifndef CLASSNAME #define CLASSNAME ... #endif

保护

我是否需要更改我的整个设计,或者什么是我的最佳选择?

base.hpp

#include "someclass.hpp"

class Base
{
    protected:
        unique_ptr<SomeClass> someClass;
};

base.cpp

#include "base.hpp"

Base::Base()
{
    this->someClass = make_unique<SomeClass>();
}

child.hpp

#include "base.hpp"

class Child : public Base
{
    public:
        void callbackFunction(std::string data);
        unique_ptr<Callback<Child>> callback;
};

child.cpp

#include "child.hpp"

void Child::callbackFunction(std::string data)
{
    /*does something*/
}

Child::Child()
{
    this->callback = make_unique<Callback<Child>>(this, &Child::callbackFunction);
    //I can call this->callback->call(data); here without problems
    
    this->someClass->setCallback(this->callback);
  //^^^^^^^^^^^^^^^ == base.someClass

}

someclass.hpp

#include "child.hpp" // < does crash compiler due to loop
//> someclass.hpp uses child.hpp
//> child.hpp uses base.hpp
//> base.hpp uses someclass.hpp
// and thus loop

class SomeClass
{
    public:
        void someFunction(std::string data);
        void setCallback(unique_ptr<Callback<Child>> callback);
        unique_ptr<Callback<Child>> callbackInstance;
};

someclass.cpp

//not 100% sure about the type of this parameter
void setCallback(unique_ptr<Callback<Child>> callback)
{
    this->callbackInstance = callback;
}

void SomeClass::someFunction(std::string data)
{
    //here I want to call this "Child::callbackFunction" which should go like "this->callbackInstance->call(data)" ?
}

也在someclass.hpp

template<class T>
class Callback
{
    public:
        Callback(T* instance, void (T::*function)(std::string))
        {
            this->callbackInstance = instance;
            this->callback = function;
        }
        void call(std::string data)
        {
            (callbackInstance->*callback)(data);
        }
    private:
        T *callbackInstance;
        void (T::*callback)(std::string);
};

解决 提到的错误(“预计 class-name 在 child.hpp 上的‘{’标记之前 class-name” ) 你应该删除 base.hpp中的#include "someclass.hpp"并用前向声明 对于 class SomeClass 如下所示。

base.hpp

#ifndef BASE_H
#define BASE_H
//NO NEED TO INCLUDE someclass.hpp
#include <memory>
class SomeClass;//FORWARD DECLARE SomeClass
class Base
{
    std::unique_ptr<SomeClass> someClass; 
    public:
    //add declaration for default constructor 
    Base();
};
#endif

base.cpp

#include "base.hpp"
#include "someclass.hpp"

//other things here

Base::Base()
{
    this->someClass = std::make_unique<SomeClass>();
}

child.hpp

#ifndef CHILD_H
#define CHILD_H
#include "base.hpp"
#include <memory>
#include "someclass.hpp"

class Child : public Base
{
    public:
        void callbackFunction(std::string data);
        std::unique_ptr<Callback<Child>> callback;
        //add declaration for default constrcutor 
        Child();
};
#endif

child.cpp

#include "child.hpp"

void Child::callbackFunction(std::string data){
    /*does something*/
}

Child::Child()
{
    this->callback = std::make_unique<Callback<Child>>(this, &Child::callbackFunction);
    //I can call this->callback->call(data); here without problems
}

someclass.hpp

#ifndef SOMECLASS_H
#define SOMECLASS_H
#include <string>
//REMOVED include child.hpp from here
class SomeClass
{
    public:
        void someFunction(std::string data);

        //I think I need an instance of Callback<Child> here?
};
template<class T>
class Callback
{
    public:
        Callback(T* instance, void (T::*function)(std::string))
        {
            this->callbackInstance = instance;
            this->callback = function;
        }
        void call(std::string data)
        {
            (callbackInstance->*callback)(data);
        }
    private:
        T *callbackInstance;
        void (T::*callback)(std::string);
};
#endif

someclass.cpp

#include "someclass.hpp"
void SomeClass::someFunction(std::string data)
{
    //here I want to call this "Child::callbackFunction" which should go like "this->callbackInstance->call(data)" ?
}

上面的程序编译执行成功,可以看出here.

总结

下面列出了我所做的一些更改:

  • 删除了不必要的包含
  • 在 child.hpp 和 base.hpp
  • 中添加了默认构造函数的声明
  • 在所有 headers.
  • 中添加了 包括守卫