C ++:当两个类包含指向另一个的指针时,如何解决派生类之间的模板循环依赖关系? [英] C++: How to solve template cyclic dependency between derived classes when two classes contain a pointer pointing to another?

查看:58
本文介绍了C ++:当两个类包含指向另一个的指针时,如何解决派生类之间的模板循环依赖关系?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个父类和一些派生自它的类.我想将eac的另一个派生类与另一个派生类配对".

I have a parent class and some classes derived from it. I want to 'pair' two derived classes that eac has a pointer to another one.

代码示例:

template<typename DerivedClassName>
class Parent {
    // some stuff
    DerivedClassName* prtToPair;
};

template<typename DerivedClassName>
class DerivedA : public Parent<DerivedClassName> {

};


template<typename DerivedClassName>
class DerivedB : public Parent<DerivedClassName> {

};

// compile fails
DerivedA<DerivedB> dA;
DerivedB<DerivedA> dB;

dA.prtToPair = &dB;
dB.prtToPair = &dA;

我知道我可以使用虚函数来做到这一点,但是我尝试找到一种使用模板的方法.

I know I can do this with virtual function but I try to find a way to use template.

我从 http://找到了解决方案qscribble.blogspot.com/2008/06/circular-template-references-in-c.html :

#include <stdio.h>

template<class Combo> struct A
{
  typedef typename Combo::b_t B;
  B* b;
};

template<class Combo> struct B
{
  typedef typename Combo::a_t A;
  A* a;
};

struct MyCombo {
  typedef A<MyCombo> a_t;
  typedef B<MyCombo> b_t;
};

int main(int argc, char* argv[])
{
  A<MyCombo> a;
  B<MyCombo> b;
  a.b = &b;
  b.a = &a;
  return 0;
}

但是它仅适用于两个固定的类A和B.考虑到我有很多派生类,并且我想将它们中的任何两个配对",我该如何解决这个问题?

but it only works for two fixed classes A and B. Consider I have many derived classes and I want to 'pair' any two of them, how can I solve this problem?

更新1.修复第一个代码块中的错字更新2.我尝试了以下代码

Update 1. fix a typo in first code block Update 2. I tried following code

template<typename DerivedClassName>
class Parent {
    // some stuff
public:
    DerivedClassName *prtToPair;
};

template<typename DerivedClassName>
class DerivedA : public Parent<DerivedClassName> {
public:
    void func() {
        std::cout << "A" << std::endl;
    }
};


template<typename DerivedClassName>
class DerivedB : public Parent<DerivedClassName> {
public:
    void func() {
        std::cout << "B" << std::endl;
    }
};

int main() {
    DerivedA<DerivedB<void>> A;
    DerivedB<DerivedA<void>> B;

    A.prtToPair = reinterpret_cast<DerivedB<void> *>(&B);
    B.prtToPair = reinterpret_cast<DerivedA<void> *>(&A);

    A.prtToPair->func();
    B.prtToPair->func();

    return 0;
}

它编译并打印了 BA .但是,此代码是否正确?有副作用吗?

It compiled and printed B A. But is this code correc? Does it have any side effect?

推荐答案

类似以下内容?

#include <type_traits>

template <typename Combo>
struct Parent {
  // some stuff
  typename Combo::other_type* prtToPair;
};

template <typename Combo>
class DerivedA : public Parent<Combo> {};

template <typename Combo>
class DerivedB : public Parent<Combo> {};

template <template <typename...> class T, template <typename...> class U>
struct Combo {
 private:
  template <typename Combo, bool B>
  struct impl {
    using other_type =
        typename std::conditional_t<B, typename Combo::type2, typename Combo::type1>;
  };

 public:
  using type1 = T<impl<Combo, true>>;
  using type2 = U<impl<Combo, false>>;
};

int main() {
  using C = Combo<DerivedA, DerivedB>;
  using A = typename C::type1;
  using B = typename C::type2;

  A dA;
  B dB;

  dA.prtToPair = &dB;
  dB.prtToPair = &dA;
}

这使这两种类型取决于与它们关联的 Combo ,并且选择正确的 other_type 是实现 Combo 的一部分代码>.请注意,虽然 Combo< DerivedA,DerivedB> Combo< DerivedB,DerivedA> 现在将导致不同的类型.

It makes the two types dependent on the Combo they are associated with and the choice of the correct other_type is made part of the implementation of Combo. Note that Combo<DerivedA, DerivedB> and Combo<DerivedB, DerivedA> will now lead to different types, though.

关于您的

通过 reinterpret_cast 返回的指针访问不相关类型的值或使用它调用非静态成员函数(如您所做的那样)会导致未定义的行为.

Accessing a value through the pointer returned by reinterpret_cast to an unrelated type or calling a non-static member function using it (as you are doing) causes undefined behavior.

这篇关于C ++:当两个类包含指向另一个的指针时,如何解决派生类之间的模板循环依赖关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆