如何控制C++中类或函数的可访问性

How the accessbility of a class or function in C++ is controlled

本文关键字:函数 访问 何控制 控制 C++      更新时间:2023-10-16

在C#等语言中。 您可以将公共或内部放在类的前面,以控制类的访问级别。如何在C++ DLL 中完成此操作?

大概你基本上是在问如何从DLL导出类。

在这种情况下,大多数Windows编译器(例如VC++,MinGW)使用__declspec(dllexport)来完成这项工作。

为了镜像这一点,客户端代码需要将类声明为 __declspec(dllimport) 。通常,您最终会得到以下结果:

#ifdef BUILD_DLL
#define DLL __declspec(dllexport)
#else
#define DLL __declspec(dllimport)
#endif
DLL class whatever { 
    // ...
};

。在标头中,用于生成 DLL 的 make 文件将定义BUILD_DLL

cflags += /DBUILD_DLL

通过将一个类嵌套在另一个类中:

class A
{
public:
    class B {};
protected:
    class C {};
private:
    class D {};
};

与 C#(或任何其他现代语言)不同C++语言标准不谈论动态库/共享对象的任何内容。

因此,语言/编译器实现者定义自己的跨 DLL/SO 导出类定义的方式完全是特定于的。

有关详细信息,请参阅 http://gcc.gnu.org/wiki/Visibility。

#if defined _WIN32 || defined __CYGWIN__
  #ifdef BUILDING_DLL
    #ifdef __GNUC__
      #define DLL_PUBLIC __attribute__ ((dllexport))
    #else
      #define DLL_PUBLIC __declspec(dllexport) // Note: actually gcc seems to also supports this syntax.
    #endif
  #else
    #ifdef __GNUC__
      #define DLL_PUBLIC __attribute__ ((dllimport))
    #else
      #define DLL_PUBLIC __declspec(dllimport) // Note: actually gcc seems to also supports this syntax.
    #endif
  #endif
  #define DLL_LOCAL
#else
  #if __GNUC__ >= 4
    #define DLL_PUBLIC __attribute__ ((visibility ("default")))
    #define DLL_LOCAL  __attribute__ ((visibility ("hidden")))
  #else
    #define DLL_PUBLIC
    #define DLL_LOCAL
  #endif
#endif
extern "C" DLL_PUBLIC void function(int a);
class DLL_PUBLIC SomeClass
{
   int c;
   DLL_LOCAL void privateMethod();  // Only for use within this DSO
public:
   Person(int _c) : c(_c) { }
   static void foo(int a);
}; 

从上面的代码片段中,您可以观察到导出类直接依赖于编译器特定的扩展。

CL/MSVC - __declspec(dllexport), __declspec(dllimport
GCC - __attribute__ ((visibility ("default")))

GCC 还提供了 **-fvisibility=[hidden|default],以便更好地控制通过 DLL/SO 导出的符号。