使用预处理器的 #ifdef 更改变量的类型
Changing type of variable using prepocessor's #ifdef
我有两个应用程序'服务器'和'客户端',它们依赖于许多相同的代码。他们需要以不同的方式与主机互动。我想在两种不同的情况下包含两个不同的类,而不是编写一个类来处理这两种情况。现在,在global .h和global .cpp中,我这样做:
上面:
#ifdef SERVER
extern ConsoleUI ui;
#else
extern Logger ui;
#endif
Globals.cpp:
#include "Globals.h"
#ifdef SERVER
ConsoleUI ui;
#else
Logger ui;
#endif
(我在header中也有include守卫,但在这里没有提到)。
在Server的主文件中,我定义:
#define SERVER
,在客户端的主文件中,我使用:
#define CLIENT
然而,它们最终都创建了一个Logger ui而不是一个ConsoleUI ui。我知道这是因为服务器试图调用存在于ConsoleUI和segfaults中的函数,因为出于某种原因,他的"ui"类型为"Logger"。
我确实意识到一种更简洁的方法可能是将Globals拆分为globalclient .h/.cpp和GlobalsServer.h/.cpp,但我想了解为什么上面的代码不起作用。
希望以前没有人问过这个问题,我搜索的所有东西都没有给我任何有用的结果。
代码可能失败的原因是,如果您执行类似#define SERVER
的操作,将创建SERVER
符号。如果你在其他地方也有#define CLIENT
,那么如下:
#include "Globals.h"
#ifdef SERVER
ConsoleUI ui;
#else
Logger ui;
#endif
实际上会进入ifdef SERVER
分支,这可能不是您想要的。
为了以您想要的方式进行条件编译,您需要使用#define
从命令行为服务器和客户端分别编译一次。执行此操作的标志通常是-D
。
使用#ifdef
方法为服务器编译你可以这样做
g++ -DSERVER -o server_output_name
客户端:
g++ -DCLIENT -o client_output_name
然而,重要的是要意识到,一般来说,在c++中有更好的方法来实现你想要的。具体来说,您希望让语言为您执行类型检查,而不是依赖相对而言"不安全"的预处理器。如果有很多共同的代码,如何做一个基类,其中包含的代码和有两个派生类,实现非共同的代码?
类似:
class UIBase{
protected:
//all the common code
};
class UIServer : public UIBase{
//server specific code and implementation
};
class UIClient : public UIBase{
//client specific code and implementation
};
这样,您可以根据对象的类型创建对象,并让c++语言确保根据上下文调用正确的代码。这样可以获得#define
方法所没有的类型安全
问题可能是您没有一致地为每个人定义SERVER
或CLIENT
。将global .h修改为:
#ifdef SERVER
#ifdef CLIENT
#error "Both CLIENT and SERVER defined!"
#endif
#define ui ServerUI
extern ConsoleUI ui;
#elif defined(CLIENT)
#define ui ClientUI
extern Logger ui;
#else
#error "Neither CLIENT nor SERVER defined!"
#endif
现在,如果你有丢失或其他损坏的服务器和/或客户端设置,你会得到一个编译器或链接器错误,而不是运行时崩溃。
请确保在主cpp中包含' global .h'之前添加了'#define SERVER'。
- 变量没有改变?通过向量的函数调用
- 在向量内更改变量的值不会改变其在向量外的值
- C++11:具有互斥锁的线程看到原子变量的值发生变化,尽管这是唯一可以改变它的代码
- 为什么我可以改变常量对象中的成员变量,这是返回常量对象函数的结果?
- 标准在哪里定义了可变变量可以改变
- C++11:可变的 lambda 似乎没有改变变量?
- printf() 似乎改变了一个变量
- 为什么我的变量在单独的线程中修改时没有改变?C++/boost
- 为什么 Player.x 和 Player.y 变量没有改变?
- C - 如何将各处的静态函数称为改变其私有变量
- 即使"friend class rect"在平方类中被评论,为什么它要改变矩形类的私有变量?
- 为什么调用 CUDA 内核函数时这个类成员变量没有改变
- 全局变量的顺序会改变C /OpenGL的性能
- 为什么一个函数的末尾有常量这个词,即使它确实改变了一个变量
- 如何在C++中改变超类和子类的变量
- setRoomName不会改变变量roomName
- 不能改变变量的值
- 是否有一种方法可以改变变量在内存中的存储方式(位大小)
- Std::cout改变变量的值
- 使用引用改变变量的地址