这样的类声明在DLL中编译时会产生警告C4251,因为std::vector<int>
只是标题而且没有dll接口:
#ifdef IS_DLL
#define EXPORT __declspec(dllexport)
#else
#define EXPORT __declspec(dllimport)
#endif
#include <vector>
class EXPORT Foo
{
public:
Foo();
~Foo();
private:
std::vector<int> m_vec;
};
但以下声明不会产生任何警告:
class Foo
{
public:
EXPORT Foo();
EXPORT ~Foo();
private:
std::vector<int> m_vec;
};
对于我来说,目前还不清楚为什么在第二种情况下(或者在第一种情况下产生的情况下)没有产生警告,因为
1)两个示例中的m_vec
都是私有的,因此如果使用正确的标头,则无法从客户端代码访问它(如果在private
中使用被黑客攻击的标头,则可以在两种情况下进行访问被public
)替换。
2)在这两种情况下dumpbin /exports
命令都显示只导出方法。第一个版本的输出(全班导出):
1 0 00001000 ??0Foo@@QAE@ABV0@@Z = ??0Foo@@QAE@ABV0@@Z (public: __thiscall Foo::Foo(class Foo const &))
2 1 00001040 ??0Foo@@QAE@XZ = ??0Foo@@QAE@XZ (public: __thiscall Foo::Foo(void))
3 2 00001060 ??1Foo@@QAE@XZ = ??1Foo@@QAE@XZ (public: __thiscall Foo::~Foo(void))
4 3 00001020 ??4Foo@@QAEAAV0@ABV0@@Z = ??4Foo@@QAEAAV0@ABV0@@Z (public: class Foo & __thiscall Foo::operator=(class Foo const &))
和第二个版本(仅限方法):
1 0 00001000 ??0Foo@@QAE@XZ = ??0Foo@@QAE@XZ (public: __thiscall Foo::Foo(void))
2 1 00001020 ??1Foo@@QAE@XZ = ??1Foo@@QAE@XZ (public: __thiscall Foo::~Foo(void))
请您解释两种情况之间的区别并给出一个小例子,其中第一种情况我们有错误,而第二种情况一切都很好(如果遵循警告逻辑)?