0

所以,我有一组相当简单的模板,我想一起使用,但编译器一直告诉我 B::a 的类型不完整。一切都提前声明了,但它仍然不起作用......

#include <iostream>

using namespace std;

template <typename T> class A;
template <typename T> class B;

template <typename T>
class A{
public:
    void ATestFunction();
    void CallBFunction();
protected:
    B<T> b;
};

template <typename T>
class B{
public:
    void BTestFunction();
    void CallAFunction();

protected:
    A<T> a;
};

template <typename T>
void A<T>::ATestFunction(){
    cout << "A was used for a function call" << endl;
}

template <typename T>
void B<T>::BTestFunction(){
    cout << "B was used for a function call" << endl;
}


template <typename T>
void A<T>::CallBFunction(){
    b.BTestFunction();
}

template <typename T>
void B<T>::CallAFunction(){
    a.ATestFunction();
}

int main()
{
    A<int> dragons;
    dragons.CallBFunction();
    return 0;
}

我问这个是因为我在编程一些相互依赖的数组类型类时遇到了一些困难(实现一个可以像这样访问的二维数组:[][]),但是这个问题发生了,并且在工作中投入了一个齿轮. 我做了这个测试程序,但它仍然失败。我在 Linux 上尝试过 MinGW 4.7.2 和 GNU g++,每个都给了我同样的问题。

4

2 回答 2

5

这段代码可以看出问题的核心:

template <typename T>
class A{
    B<T> b;
};

template <typename T>
class B{
    A<T> a;
};

C++ 是一种具有值语义的语言,这意味着它B<T> b;表示类型的对象B<T>(而不是引用,如 Java 或 C# 中的引用类型)。也就是说,A<T> 包含一个B<T>. 现在,如果您查看B模板的定义,您会看到它又包含一个A<T>子对象。这基本上是不可能的,因为A<T>不可能包含包含A<T>. A<T>物体的大小是多少?

在不知道要解决的真正问题的情况下,我不会冒险推荐一种方法,但是您可以考虑使用指针(A<T>将包含指向 的指针B<T>而不是完整的B<T>子对象;或者类似地,可以B<T>包含指向A<T>; 或两者的指针),或参考资料。但也可能是更深层次的重新设计可能更有意义。

于 2013-04-04T01:15:18.097 回答
0

即使您使用指针,也无法正常工作。这基本上会触发创建 A 和 B 的无限循环

A创造B创造A创造B创造A...

这会奏效。

#include <iostream>

using namespace std;

template<typename T> class A;
template<typename T> class B;

template<typename T>
class A
{
public:
    A()
    {
        b = new B<T>(this);
    }
    A(B<T>* pb)
    {
        b = pb;
    }
    void ATestFunction()
    {
        cout << "A was used for a function call" << endl;
    }
    void CallBFunction()
    {
        b->BTestFunction();
    }
protected:
    B<T>* b;
};

template<typename T>
class B
{
public:
    B()
    {
        a = new A<T>(this);
    }
    B(A<T>* pa)
    {
        a = pa;
    }
    void BTestFunction()
    {
        cout << "B was used for a function call" << endl;
    }
    void CallAFunction()
    {
        a->ATestFunction();
    }

protected:
    A<T>* a;
};

int main()
{
    A<int> dragons;
    dragons.CallBFunction();

    B<int> bdragons;
    bdragons.CallAFunction();
    return 0;
}

或者也许只是使用静态函数

#include <iostream>

using namespace std;

template<typename T> class A;
template<typename T> class B;

template<typename T>
class A
{
public:
    static void ATestFunction()
    {
        cout << "A was used for a function call" << endl;
    }
    void CallBFunction();

};

template<typename T>
class B
{
public:
    static void BTestFunction()
    {
        cout << "B was used for a function call" << endl;
    }
    void CallAFunction();

};
template<typename T>
void A<T>::CallBFunction()
{
    B<int>::BTestFunction();
}


template<typename T>
void B<T>::CallAFunction()
{
    A<int>::ATestFunction();
}

int main()
{
    A<int> dragons;
    dragons.CallBFunction();

    B<int> bdragons;
    bdragons.CallAFunction();
    return 0;
}
于 2013-04-04T01:53:53.520 回答