使用#define宏来标准化类声明

时间:2013-05-21 13:13:00

标签: c++ class c-preprocessor

我正在为我的一个项目构建一个C ++ DLL。我试图标准化类定义的方式。所以不要每次都写作:

class __declspec(dllexport) ClassName

我正在构建一个#define宏来简化此过程:

#define CLASS( cName ) class __declspec(dllexport) cName

但是,当我使用它时,它会给我以下错误:

Error: Expected a ';'

我知道你可以使用#define宏来定义整个类的创建,但它是否可以用来定义“类头”?

谢谢,

请记住,我正在努力这样做,因为我们要处理数百个课程,所以这些“自动化”最有帮助:)

编辑:

示例:

#define CLASS( nClass ) class __declspec(dllexport) nClass

CLASS( APTest )
{                        // Here is the error of missing ';'
public:
    APTest();
};

2 个答案:

答案 0 :(得分:14)

不要这样做。

C ++已经标准化了!

如果您希望其他人阅读您的代码,那么只需用传统的C ++编写,而不是一些看起来不同的家庭式方言。习惯了正确的C ++语法,它可以更容易地阅读其他人的C ++代码。

有一点有意义的是简化__declspec部分,你可以这样做:

#ifdef _WIN32
#define DLLEXPORT __declspec(dllexport) 
#else
#define DLLEXPORT
#endif

class DLLEXPORT APTest
{
    // ...
};

通过撰写CLASS( APTest ),你真的不会让你的生活变得更简单,让别人更难理解。说不。

答案 1 :(得分:1)

有一种比@Wakely更好的方法。这样做:

#ifdef MYLIB_DLL

#ifndef MYLIB_IFACE
#ifdef MYLIB_IFACE_EXPORT
#define MYLIB_IFACE _declspec( dllexport )
#else  // !MYLIB_IFACE_EXPORT
#define MYLIB_IFACE _declspec( dllimport )
#endif // !MYLIB_IFACE_EXPORT
#endif // !MYLIB_IFACE

#else  // !MYLIB_DLL

#ifndef MYLIB_IFACE
#define MYLIB_IFACE
#endif // !MYLIB_IFACE

将这样的块放在dll中每个文件使用的标题中,并放在dll的公共标题中。

应该从您的dll导出的每个符号都会被标记为:

class MYLIB_IFACE MyClass 
{
};

void MYLIB_IFACE myFunc();

然后在你的dll中的每个.cpp文件中,第一行应该是:

#define MYLIB_IFACE_EXPORT

如果你这样做,那么它将在不使用dllexport / dllimport的POSIX系统上构建得很好。要构建lib的dll版本,请定义MYLIB_DLL。 (您可以在编译器的标志中执行此操作,以便可以从构建系统进行控制)

要构建lib的静态版本,请不要定义MYLIB_DLL。

@Update:

你可以扩展它以支持GCC的相似性:

#ifdef WIN32
#define KX_SYMBOL_EXPORT _declspec( dllexport )
#define KX_SYMBOL_IMPORT _declspec( dllimport )
#else // GCC
#define KX_SYMBOL_EXPORT __attribute__(( visibility ("default")))
#define KX_SYMBOL_IMPORT 
#endif

#ifdef KX_DLL

#ifndef KX_IFACE
#ifdef KX_IFACE_EXPORT
#define KX_IFACE KX_SYMBOL_EXPORT
#else  // !KX_IFACE_EXPORT
#define KX_IFACE KX_SYMBOL_IMPORT
#endif // !KX_IFACE_EXPORT
#endif // !KX_IFACE

#else  // !KX_DLL

#ifndef KX_IFACE
#define KX_IFACE
#endif // !KX_IFACE

#endif // !KX_DLL

为简单起见,我在第一个示例中删除了GCC位。但这就是真正做到的。 @Wakely是对的。