c++ - 模板类中的循环依赖

标签 c++ circular-dependency

我遇到了模板类循环依赖的问题。我有类似以下内容,

// A.hxx
template<typename T>
class B;

template<typename T>
class C;

template<typename T>
class A
{
    A(T const& x, T const& y, T const& z)
    {
        data[0] = x;
        data[1] = y;
        data[2] = z;
    }

    A(B<T> const& b) :
     A(b.x(),b.y(),b.z())
    {}

    A(C<T> const& c) :
     A(c.x(),c.y(),c.z())
    {}


    T x() {return data[0];}
    T y() {return data[1];}
    T z() {return data[2];}

    T data[3];
};



// B.hxx
template<typename T>
class A;

template<typename T>
class C;

template<typename T>
class B
{
    B(T const& y, T const& z, T const& x)
    {
        data[0] = y;
        data[1] = z;
        data[2] = x;
    }

    B(A<T> const& a) :
     B(a.y(),a.z(),a.x())
    {}

    B(C<T> const& c) :
     B(c.y(),c.z(),c.x())
    {}

    T x() {return data[2];}
    T y() {return data[0];}
    T z() {return data[1];}

    T data[3];
};



// C.hxx
template<typename T>
class A;

template<typename T>
class B;

template<typename T>
class C
{
    C(T const& z, T const& x, T const& y)
    {
        data[0] = z;
        data[1] = x;
        data[2] = y;
    }

    C(A<T> const& a) :
     C(a.z(),a.x(),a.y())
    {}

    C(B<T> const& b) :
     C(b.z(),b.x(),b.y())
    {}

    T x() {return data[1];}
    T y() {return data[2];}
    T z() {return data[0];}

    T data[3];
};

前向声明不起作用。我曾尝试打破声明中的定义,并在声明该类后包含相关的 hxx 文件,但也没有成功。任何帮助,将不胜感激。谢谢

最佳答案

在那种特殊情况下,我会尝试通过使用接口(interface)或父类(super class)来消除循环依赖。基础知识:为了消除循环依赖,每个真正的类都继承自一个仅声明在其他类中使用的方法的父类(super class)。它可能实现不依赖于其他类的那些,或者仅仅是一个接口(interface)(只有虚方法)。唯一的规则是你必须只使用指针或引用其他类的对象来避免切片问题。这里更简单,因为所有类都继承自一个公共(public)类,但在更一般的用例中,每个类都可以有自己的父类(super class)。可能是:

D.hxx

#ifndef _D
#define _D

template<typename T> 
class D {
public:
    virtual T x() const = 0;
    virtual T y() const = 0;
    virtual T z() const = 0;
    virtual ~D() = 0;    // better to add a virtual destructor...
};

#endif

这样,其他文件就变成了(比如 A.hxx):

#include "d.h"

template<typename T>
class A: public D<T>
{
public:
    A(T const& x, T const& y, T const& z)
    {
        data[0] = x;
        data[1] = y;
        data[2] = z;
    }

    A(class D<T> const& d): A(d.x(), d.y(), d.z()) {} // for C++11 and above...

    T x() const { return data[0]; }
    T y() const { return data[1]; }
    T z() const { return data[2]; }

private:
    T data[3];
};

它在这里起作用,因为您只使用来自其他类的对象的引用,所以您只需要声明。但我不知道它是否适用于您的实际用例。

无论如何,如前所述,这里只使用公共(public)父类(super class)是因为它很简单,但是您可以为每个类使用一个接口(interface)或父类(super class)

关于c++ - 模板类中的循环依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33808601/

相关文章:

c++ - 通过 QMetaObject::invoke 调用 QListView setModel 问题

c++ - 获取 Win32 二进制文件中的类偏移量

typescript - Typescript、CommonJS 和 Browserify 的循环依赖问题

c++ - 容器的元素如何访问其容器的 "owner"?

c++ - 运行时错误: Integer Overflow for Complement Number Problem

c++ - 具有静态链接的成员函数

c++ - 我们应该通过引用还是按值传递 shared_ptr ?

javascript - 检测到循环依赖项中的警告 : barrelsby Angular 10

android - Dagger 在单独的 gradle 模块中

python - 循环依赖导致 ImportError : cannot import name