具有继承模板类的循环依赖关系
Circular Dependency with Inherited Template Class
我遇到了一个循环依赖问题。基本上我有两个类,第一个是模板类,它使用了第二个类中的一些功能。第二个类继承自我的模板类。
以下是一个简化的结构:
// Foo.h
#pragma once
#include "Bar.h"
template <class T> class Foo
{
public:
void DoSomething();
};
template <class T> void Foo<T>::DoSomething()
{
Bar::GetInstance()->LogEvent();
}
//Bar.h
#pragma once
#include "Foo.h"
class Bar : public Foo<Bar>
{
public:
static Bar* GetInstance();
void LogEvent();
};
//Bar.cpp
#include "Bar.h"
Bar* Bar::GetInstance()
{
// return instance of Bar singleton class
}
void Bar::LogEvent()
{
// log some event in a file
}
现在的问题是,当我编译代码时,我在bar.h 中得到以下错误
Bar.h() : error C2504: 'Foo' : base class undefined
Bar.h() : error C2143: syntax error : missing ',' before '<'
据我所知,这绝对是一个依赖性问题。如果我从"DoSomething"中删除对"LogEvent"的调用,并从Foo.h中删除引用"Bar.h",问题就会消失。
然而,这并不是一个真正的解决方案,因为Foo需要Bar包含的功能,相反,Bar继承自Foo,需要包含对Foo.h的引用。
那么,我该如何解决这个问题?我看过其他关于循环推荐的帖子,但我一直没能解决这个问题。
感谢
根据您发布的代码,foo.h不需要包含bar.h,如果不包含,问题就会消失。
重要的是,编译器在看到Bar之前先看到Foo,如果#include "bar.h"
位于Foo.h的顶部(取决于Foo.h和Bar.h在消费模块中的#include
-ed顺序),则可能不会发生这种情况。
也就是说,如果基类需要假设一个特定的派生类并按名称调用它,那么可能存在设计问题(基类中的虚拟函数会起作用吗?)。但我不能在没有看到全貌的情况下做出这样的判断。
根据下面的评论,我认为你可以通过添加第三个文件来解决眼前的问题:
// LogEvent.h
void LogEvent(...);
// LogEvent.cpp
#include "bar.h"
void LogEvent(...)
{
Bar::GetInstance()->LogEvent(...);
}
然后修改foo.h如下:
// Foo.h
#pragma once
#include "LogEvent.h"
template <class T> class Foo
{
public:
void DoSomething();
};
template <class T> void Foo<T>::DoSomething()
{
LogEvent(...);
}
除非还有其他问题,否则这至少会让你编译。
您的问题是函数的定义:
template <class T> void Foo<T>::DoSomething()
{
Bar::GetInstance()->LogEvent();
}
您不需要在这里写Bar
类名。
用途:
template <class T> void Foo<T>::DoSomething()
{
T::GetInstance()->LogEvent();
}
这样,当您编写Foo<Bar>
时,Bar
将替换T
。
我用你发布的代码测试了这个变化,它起了作用。
编辑:
我找到了一个使用模板专业化的解决方案。
将此添加到您的Foo.h
:
template <>
class Foo<Bar>
{
public:
void DoSomething()
{
Bar::GetInstance()->LogEvent();
}
};
这解决了你所有的问题。使用模板专用化,如果模板Foo
是以Bar
类型作为参数实例化的,那么您将实例化上面定义的类,而不是原始的Foo
。
因此,您不必再担心其他类没有方法GetInstance
。您可以使用这种方法来扩展代码,并根据需要使用任意数量的Foo
专业化。
- C++GTKMM gui循环依赖关系
- 如何在头文件中声明类模板(由于循环依赖关系)
- 如何在具有循环依赖的类中dynamic_cast?
- C++模板方法中的循环依赖关系
- 修复循环依赖项 c++17 标头
- 涉及全局对象的循环依赖C++
- 循环依赖,在继承类的情况下使用覆盖方法
- Wt::D bo 中的循环依赖关系
- 在包含窗口标头时难以解决循环依赖关系问题
- 解决循环依赖关系 c++ 的想法
- C++循环依赖关系,未声明的标识符
- C++ 中的循环依赖关系问题
- 错误 C2512 视觉C++(并且不是循环依赖项)
- CMake 外部和内部静态库的循环依赖关系
- 正在从继承中解析循环依赖项
- "std::shared_ptr"循环依赖关系是如何导致问题的
- 纯引用而不是weak_ptr来打破循环依赖关系
- "invalid use of incomplete type" .解决循环依赖关系
- 如何避免模板方法的循环依赖
- 循环依赖结构,使用前向声明时结构的错误重定义