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)
你能解决我的问题吗?我的想法:(
你有一个循环依赖: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另一种选择是重新考虑全局变量是否是正确的解决方案.