2

这看起来很简单,但我没有解决这个问题的好主意。最小的例子:

template<class T>
struct C {
    typename T::t var;
};

class B;
struct A : public C<B> {
    typedef int t;
};

struct B
{
    A a;
};

int main() { return 0; }

我知道它可以通过给 C 少 B 来解决:

template<class t>
struct C {
    t var;
};

struct A : public C<int> {
};

但这并不令人满意(特别是因为 B 有很多我在 C 中真正需要的类型定义和静态函数)。有什么更好的办法来解决这个问题吗?

4

2 回答 2

2

如果您可以制作A模板,那么以下应该可以工作...

template<class T>
struct C {
    typename T::t var;
};

template <typename BaseType>
struct A : public C<BaseType> {
  int i;
};

struct B
{
  typedef int t;
  A<B> a;
};


typedef A<B> AType;

int main() {

  AType a;
  a.i = 1;
  a.var = 1;
  B c;
  c.a.i =0;

  return 0;

}
于 2013-10-17T08:45:11.210 回答
1

首先,如果你想让一个类成为基类,它的类型必须是完整的,比如

struct A : public C<B> 

在这种情况下B必须是完整类型。

其次,如果您声明一个类类型成员,除非您定义一个指针,否则它的类型需要是完整的。

struct B
{
    A a;  // A must be complete type
};

所以你不能A继承BB拥有成员。但是您可以将一个转换为指针。对于示例,以下应该没问题:

class A;

struct B
{
    A* a;           // imcomplete type is fine
    typedef int t;
};

struct A : public C<B> {         
};

通常,如果您遇到此类问题,则意味着您的课程中存在设计问题。也许你正在制作monolith classes.

如果您遵循良好的指导方针:

1 one class (or function), one responsibility. 
2 Where possible, prefer writing functions as nonmember nonfriends.

您将减少此类问题。

于 2013-10-17T08:23:20.987 回答