有關C和C++編碼標準的最佳實踐是什麼?是否允許開發人員將它們混合在一起。鏈接C和C++對象文件時是否有任何複雜性。C和C++編碼標準
傳統上用C編寫的套接字庫應該保留在C中並保存在獨立的源文件中嗎?這就是保存.c文件和C++代碼在.cpp文件中的c代碼。 在使用g ++進行語法分析之後混合使用c和C++時,會有任何性能損失,因爲類型安全檢查不在C中完成?但在C++中。將是鏈接C和C++源代碼文件的最佳方式。
有關C和C++編碼標準的最佳實踐是什麼?是否允許開發人員將它們混合在一起。鏈接C和C++對象文件時是否有任何複雜性。C和C++編碼標準
傳統上用C編寫的套接字庫應該保留在C中並保存在獨立的源文件中嗎?這就是保存.c文件和C++代碼在.cpp文件中的c代碼。 在使用g ++進行語法分析之後混合使用c和C++時,會有任何性能損失,因爲類型安全檢查不在C中完成?但在C++中。將是鏈接C和C++源代碼文件的最佳方式。
最大的問題是從C++代碼調用C函數,反之亦然。在這種情況下,您需要確保使用extern "C"
將該功能標記爲「C」連接。您可以直接使用頭文件做到這一點:
#if defined(__cplusplus)
extern "C" {
#endif
extern int myfunc(const char *param, int another_one);
#if defined(__cplusplus)
}
#endif
您需要#if
是因爲,包括它不會明白extern "C"
C代碼。
如果你不想(或不能)改變頭文件,你可以在C++代碼做到這一點:
extern "C" {
#include "myfuncheader.h"
}
您可以標記一個C++函數具有C鏈接相同方式,然後你可以從C代碼中調用它。你不能爲重載函數或C++類做到這一點。
除此之外,混合C和C++應該沒有問題。我們有許多數十年的C函數,它們仍然被我們的C++代碼使用。
C++在運行時不會執行「類型安全檢查」,除非您要求(使用dynamic_cast
)。 C++與C高度兼容,因此您可以隨意調用C庫並使用C++編譯器編譯C代碼。 C++並不意味着「面向對象」,並且你不應該因使用它而受到性能損失。
如果您將使用gcc編譯的代碼與g ++混合使用,請參閱Graeme的答案。
如果你用g ++編譯你所有的源代碼,那麼它全部用C++對象文件編譯(即用適當的名稱修飾和C++ ABI)。
如果您正在構建需要使用C ABI的顯式C應用程序所使用的庫,則只需使用extern「C」技巧。
如果一切都被編譯成一個可執行文件,然後使用g ++以及如果在C++這就要求在C函數依次調用C++其他功能的功能對待一切,因爲C++
,這以後函數拋出一個應該被第一個函數捕獲的異常,除非您告訴C編譯器啓用異常處理表的生成,否則您可能會遇到問題。
海灣合作委員會,這是-fexceptions
參數,默認情況下爲C++啓用,但默認C.
禁用這裏沒有良好的硬性規定。
如果最終產品將始終與C++ main()鏈接,那麼它並不重要。因爲你總是可以創建標題來做正確的事情。
如果您要創建一個需要C和C++接口的庫,但不能假設C++鏈接器,那麼您需要確保將C API與C++完全分開。在這一點上它通常是清潔做在C中的所有工作,並使用C++類代理到C.
例如:
/* c header */
struct CData
{ /* stuff */ };
void init(CData* data);
void fini(CData* data);
int getSomething(CData* data);
void doSomething(CData* data, int val);
// c++ header
extern "C" {
#include cdata.h
};
class CppData : private CData
{
public:
CppData() { ::init((CData*)this); }
~CppData() { ::fini((CData*)this); }
int getSomething() { return ::getSomething((CData*)this); }
void doSomething(int val) { :: doSomething((CData*)this, val); }
};
我希望這有助於。
一般應該假設C++可以拋出異常,因此塊中的c包裝函數應該捕獲它們,並將它們變形爲可供c調用者消化的錯誤代碼。
extern "c"
{
int nice_c_function_interface
(
void
)
{
int returnStatus;
try
{
returnStatus = nice_cpp_function();
}
catch (NiceCppException& that)
{
returnStatus = that.failure_code();
}
catch (...)
{
cerr << "Oh Worse! an unexpected unknown exception" << endl;
returnStatus = -1; // Horrible unknown failure
}
return returnStatus;
}
}
只是一個細節,但C++編譯器編譯C有一個內置的C編譯器。 C和C++有不同之處。 – tloach 2008-11-12 13:01:26