具有非导出数据成员的导出类

Bor*_*ein 5 c++ visibility shared-libraries

我希望有一个foo导出类的共享库Foo。作为实现细节,我们假设有一个我不想公开的Foo类的私有数据成员。Detail

\n\n

问题1:导出具有非导出类型的私有数据成员的类可以吗?

\n\n

(我的理解:是的)

\n\n
\n\n

我正在编译以下代码g++ -c -fPIC -o foo.o foo.cpp

\n\n
/* foo.h */\n\n#pragma once\n#define FOO_API   __attribute__((visibility("default")))\n#define FOO_LOCAL __attribute__((visibility("hidden")))\n\nclass FOO_LOCAL Detail {\n\n};\n\nclass Foo {\n    Detail d_;\n};\n\n/* foo.cpp */\n\n#include "foo.h"\n\n// nothing\n
Run Code Online (Sandbox Code Playgroud)\n\n

在 Ubuntu 16.04 64 位上的 gcc 4.6.0 下,我收到以下警告:

\n\n
foo.h:8:7: warning: \xe2\x80\x98Foo\xe2\x80\x99 declared with greater visibility than the type of its field \xe2\x80\x98Foo::d_\xe2\x80\x99 [-Wattributes]\n class Foo {\n   ^\n
Run Code Online (Sandbox Code Playgroud)\n\n

问题2:为什么会出现警告?

\n\n

我确实知道它Foo比其数据成员的类型具有更大的可见性Foo::d_:这是故意的。但为什么会出现警告呢?是 gcc 过于热心,还是我的代码存在真正的潜在问题?

\n\n
\n\n

如果我将声明更改Foo为:

\n\n
class FOO_API Foo {\n    Detail d_;\n};\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后警告消失,但没有任何变化:Foo仍然具有比 更高的可见性Foo::d_

\n\n

问题3:如果不带警告FOO_API,为什么不带警告FOO_API

\n\n

(注意:我知道这也是使用 进行编译的选项-fvisibility=hidden。这样做时我没有收到任何警告。但在这个问题中,我假设我们不使用 进行编译-fvisibility=hidden

\n