ClientClass不命名类型.GCC Linux

Kno*_*bik 3 c++ linux ubuntu gcc

在制作我的代码时,我遇到了一个奇怪的问题.我为所有包含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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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

Tim*_*tin 5

你有一个循环依赖:includes.h -> clientclass.h -> includes.h.如何解决这个问题取决于首先包含哪个标题,但它总是会令人困惑.最有可能是它造成了这条线

#include <clientclass.h>
Run Code Online (Sandbox Code Playgroud)

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

要解决此问题,您可能只能删除includes.hfrom 的包含clientclass.h,如果它不用于任何内容.如果使用from中的类型,则includes.h可以使用forward-declarations,声明类存在而不定义它,例如

class ClientClass;
Run Code Online (Sandbox Code Playgroud)

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

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

class MyClass;

MyClass * globalPointer;

void doSomething(const MyClass & foobar);
Run Code Online (Sandbox Code Playgroud)

没有MyClass范围的定义.这里的两个表达式仅MyClass通过指针或引用使用.但以下方法不起作用:

class MyClass;

void doSomethingElse() {
    MyClass theobject;
    doSomething(theobject);
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

另一种选择是重新考虑全局变量是否是正确的解决方案.