3

我的学校项目遇到了一些麻烦。

我有一堂课:

#include "Group.h"
#include <vector>
#include <string>
using namespace std;

class User{
    private :
        string username;
        vector<Group*> groups;
        void show() {
            for(int i=0; i<groups.size(); i++)
                cout << groups[i]->getName() << "\n";
        }
        string getUsername(){return username;}

};

#include "User.h"
#include <vector>
#include <string>
using namespace std;

class Group{
    private :
        string name;
        string getName(){return name;};
        User *f;
        vector<User*> m;
        void show(){
            for(int i=0; i<m.size(); i++)
                cout << m[i]->getUsername() << "\n";
        }
};

当我尝试编译它时,它给了我错误:

E:\Group.h|31|error: ISO C++ forbids declaration of 'User' with no type| E:\Group.h|31|error: expected ';' before '*' token|
E:\Group.h|33|error: 'User' was not declared in this scope|
E:\Group.h|33|error: template argument 1 is invalid|
E:\Group.h|33|error: template argument 2 is invalid|
E:\Group.h|36|error: 'User' was not declared in this scope|
E:\Group.h|36|error: template argument 1 is invalid|
E:\Group.h|36|error: template argument 2 is invalid|
E:\Group.h|47|error: 'User' has not been declared|
E:\Group.h|47|error: 'User' was not declared in this scope|
E:\Group.h|47|error: template argument 1 is invalid|
E:\Group.h|47|error: template argument 2 is invalid|
E:\Group.h|58|error: ISO C++ forbids declaration of 'User' with no type| E:\Group.h|58|error: expected ';' before '*' token|
E:\Group.h|59|error: 'User' has not been declared|
E:\Group.h|60|error: 'User' was not declared in this scope|
E:\Group.h|60|error: template argument 1 is invalid|
E:\Group.h|60|error: template argument 2 is invalid|
E:\Group.h|61|error: 'User' was not declared in this scope|
E:\Group.h|61|error: template argument 1 is invalid|
E:\Group.h|61|error: template argument 2 is invalid| ||=== Build finished: 21 errors, 4 warnings ===|

怎么了?

只有当我添加class User;到 Group.h 文件和class Group;User.h 文件时它才会编译,但这不是我寻找正确解决方案的重点,而不仅仅是临时解决方案。

我的整个项目: http ://www.speedyshare.com/jXYuM/proj.tar

4

3 回答 3

17

你有一个周期性的依赖。这两个文件需要相互编译。

尝试在组中前向声明用户:

#include <vector>
#include <string>

class User;

class Group{
    private :
        std::string name;
        std::string getName(){return name;};
        User *f;
        std::vector<User*> m;
        void show(); 
};

组.cpp

#include "Group.h"
#include "User.h"

using namespace std;

class Group
{
    .....

    void show() {
        for(int i=0; i<m.size(); i++)
        cout << m[i]->getUsername() << "\n";
    }

    .....
 }

然后在 Group.cpp 文件中,包括用户。

您可以随时在标头中转发声明对象大小不取决于您转发声明的对象的实际大小。在这种情况下,(在组中)您使用用户作为指针,因此组的大小不依赖于用户的大小,它只存储一个与用户大小无关的指针。

另一个应该有所帮助的花絮是在头文件中包含名称空间(在您的情况下为 std)是一种不好的做法。您应该删除“使用”语句并改为使用 std::vector 。在 cpp 文件中使用“使用”很好,因为其他代码不会“包含”您的源代码。

于 2012-07-05T11:26:54.503 回答
4

您在标头中有循环依赖。您可以通过将实现移动到.cpp文件并转发声明您使用的类来修复它:

#include <vector>
#include <string>

class Group; // forward declaration

class User{
    private :
        std::string username;
        std::vector<Group*> groups;
        void show();
};

#include <vector>
#include <string>

class User; // forward declaration

class Group{
    private :
        std::string name;
        std::string getName(){return name;};
        User *f;
        std::vector<User*> m;
        void show();
};

然后,在您的实现文件中,您可以包含标头。

另请注意,您应避免using namespace std在标头和大范围中使用。

于 2012-07-05T11:24:18.747 回答
2

正在使用模板。您正在使用vector,这是一个模板。

您收到错误是因为当您到达代码的以下部分时未定义 User 类:

User *f;
vector<User*> m;

为什么它没有被定义——毕竟你包括了 User.h 标头?是的,但是 User.h 标头还包括 Group.h 标头,因此必须先读取两者之一。

要解决此问题,您需要更改标题,以便其中只有一个包含另一个(或者它们都不包含另一个)。为此,您首先需要将您的方法定义移动到一个 c++ 文件中,这样对其他类的方法的方法调用就不会出现在标题中。然后您可以前向声明另一个类并删除#include。

于 2012-07-05T11:26:05.280 回答