C ++:当两个类包含指向另一个的指针时,如何解决派生类之间的模板循环依赖关系? [英] C++: How to solve template cyclic dependency between derived classes when two classes contain a pointer pointing to another?
问题描述
我有一个父类和一些派生自它的类.我想将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屋!