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メンバーとして持つことはできません。ただし、1 つをポインターに変換することはできます。サンプルの場合、以下で問題ありません。

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 に答える