簡體   English   中英

使用前置程序的#ifdef更改變量的類型

[英]Changing type of variable using prepocessor's #ifdef

我有兩個依賴於許多相同代碼的應用程序“服務器”和“客戶端”。 他們需要與控制台交互的方式有所不同。 我不想編寫處理這兩種情況的類,而是想在兩種不同的情況下包括兩種不同的類。 現在,在Globals.h和Globals.cpp中,我這樣做:

Globals.h:

#ifdef SERVER
extern ConsoleUI ui;
#else
extern Logger ui;
#endif

Globals.cpp:

#include "Globals.h"
#ifdef SERVER
ConsoleUI ui;
#else
Logger ui;
#endif

(我在標頭中也包含了防護,但在這里將它們保留了下來)。

在服務器的主文件中,我定義:

#define SERVER

在客戶端的主文件中,我使用:

#define CLIENT

但是,他們兩個最終都創建了Logger ui而不是ConsoleUI ui。 我知道這是因為服務器嘗試調用ConsoleUI和segfaults中存在的函數,因為由於某種原因,他的“ ui”屬於“ Logger”類型。

我確實意識到,更干凈的方法可能是將Globals分離為GlobalsClient.h / .cpp和GlobalsServer.h / .cpp,但是我想了解為什么上面的代碼不起作用。

希望以前沒有問過這個問題,我搜索的所有內容都沒有給我帶來任何幫助。

您擁有的代碼很可能失敗的原因是,如果您執行諸如#define SERVER ,它將創建SERVER符號。 如果您在其他地方也有#define CLIENT則請執行以下操作:

#include "Globals.h"
#ifdef SERVER
ConsoleUI ui;
#else
Logger ui;
#endif

實際上會ifdef SERVER可能不是您想要的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方法獲得某種類型的安全性。

問題可能是您沒有對每個人都正確地定義SERVERCLIENT 將Globals.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

現在,如果缺少SERVER和/或CLIENT的設置或其他損壞的設置,您將得到編譯器或鏈接器錯誤,而不是運行時崩潰。

確保在主cpp中包含“ Globals.h”之前放入“ #define SERVER”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM