如果导出成员仅起作用,则不会生成C4251警告

时间:2016-09-29 23:32:18

标签: c++ templates visual-c++ dll dllexport

这样的类声明在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))

请您解释两种情况之间的区别并给出一个小例子,其中第一种情况我们有错误,而第二种情况一切都很好(如果遵循警告逻辑)?

0 个答案:

没有答案