ClientClass不命名类型。 GCC Linux

时间:2011-02-16 16:56:48

标签: c++ linux gcc ubuntu

在制作我的代码时,我遇到了一个奇怪的问题。我为所有包含1个文件,让我们称之为includes.h和类文件,如clientclass.h等。

问题是,当我尝试编译我的代码时,我得到编译器错误:

  

/mnt/orange-new/units/includes.h|34|error:   'ClientClass'没有命名类型|

包括:

#ifndef INCLUDES_H_INCLUDED
#define INCLUDES_H_INCLUDED

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <errno.h>

#include <sys/timeb.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <arpa/inet.h>

#include <time.h>

#include <iostream>
#include <cstring>
#include <string>

#include "config.h"

#include "console.h"
#include "clientclass.h"
#include "tcpparser.h"
#include "netmsg.h"

#include "main.h"

Console Konsola;
ClientClass Clients;

TCPThread ParserTCP;

#endif // INCLUDES_H_INCLUDED

clientclass.h:

#ifndef CLIENTCLASS_H_INCLUDED
#define CLIENTCLASS_H_INCLUDED

#include "includes.h"

struct ClientStruct {

    int Sock;
    int Ident;
    int Room;

    std::string Name;
    std::string IP;

};

class ClientClass {
    public:
        ClientClass(); // create

        int Add();
        void Delete(int index);
        int Count();

        ClientStruct Client[MAX_CLIENTS];

    protected:
        void Reset(int index);

    private:
        int _count;

};

#endif // CLIENTCLASS_H_INCLUDED

你能帮我解决我的问题吗?我的想法:(

5 个答案:

答案 0 :(得分:5)

您有一个循环依赖:includes.h -> clientclass.h -> includes.h。如何解决这个问题取决于首先包含哪个标题,但它总是会令人困惑。最有可能的是它导致了行

#include <clientclass.h>

成功但未能包含内容,因为即使内容尚不存在,已经定义了包含保护CLIENTCLASS_H_INCLUDED

要解决此问题,您可能只能从includes.h删除clientclass.h的内容,如果它不用于任何内容。如果使用includes.h中的类型,则可以使用前向声明,声明类存在而不定义它,例如。

class ClientClass;

通过这种方式,您可以使用ClientClass的指针和引用,而无需包含clientclass.h。你不能做的是声明前向声明类型的,因为编译器必须知道关于类型的所有内容(至少它有多大)才能保留内存的值那种类型。如果你需要这个,你可能需要将标题分成更小的部分,并且只包括你所依赖的小部分。

因此,例如,您可以执行以下操作:

class MyClass;

MyClass * globalPointer;

void doSomething(const MyClass & foobar);

在范围内没有MyClass的定义。这里的两个表达式仅通过指针或引用使用MyClass。但以下情况不起作用:

class MyClass;

void doSomethingElse() {
    MyClass theobject;
    doSomething(theobject);
}

这需要在堆栈上为MyClass类型的对象保留空间。如果没有范围内MyClass的定义,编译器无法知道要分配多少内存。

在您的情况下,您要定义ClientClass类型的全局值,这需要ClientClass的完整定义,而不仅仅是前向声明。你有几个选择:

  • 进一步细分包含文件,以便只包含您需要的小部分
  • 按指针保存全局值,并在包含ClientClass
  • 的完整定义后,将其分配到代码中的某个位置

另一个选择是重新考虑全局变量是否在这里是正确的解决方案。

答案 1 :(得分:4)

我有点困惑为什么你有一个clientclass.h,其中包括includes.h,其中包括clientclass.h

我认为这个问题可能存在于某个地方。 你不应该这样做。

答案 2 :(得分:0)

也许是因为交叉包括..你是否通过添加

尝试了类型的前向声明
class ClientClass;
includes.h

之前的ClientClass Clients

答案 3 :(得分:0)

当您的标题布局时,除了“includes.h”之外的任何地方都不可能包含“clientclass.h”。那是因为在这种情况下,全局实例最终会在“clientclass.h”中定义类之前被声明

如果包含“clientclass.h”,那么它首先要做的是引入“includes.h”,包括用它声明的全局变量。

尝试仅包含“clientclass.h”标题需要<string>(以及MAX_CLIENTS来自的标题)的内容。

答案 4 :(得分:0)

尝试使用前向声明后,我最终得到一个错误:

  

/mnt/orange-new/units/includes.h|37|error:   聚合'ClientClass客户'有   不完整的类型,不能定义|

编辑: 将includes.h拆分为2个文件classes.h和includes.h解决了这个问题。我非常感谢大家的帮助。在如此低的时间里,我从来没有想到过这么多答案:)期待我更频繁地来到这里。谢谢。