【问题标题】:Not necessary to export class with only virtual/inline functions?不需要仅使用虚拟/内联函数导出类吗?
【发布时间】:2009-02-14 23:29:10
【问题描述】:

在 Win32 上的 C++ 中:

假设我有一个带有声明类的头文件的 DLL。 DLL 导出一些获取指向该类实例的指针/引用的方法,例如工厂函数。

如果只在其实例上调用虚函数或内联函数,我是否认为没有必要使用 __declspec 将该类标记为导出?

相反,如果想调用非虚成员函数,是否需要导出类声明?

【问题讨论】:

    标签: c++ winapi dll


    【解决方案1】:

    如果只在其实例上调用虚函数或内联函数,我是否认为没有必要使用 __declspec 将该类标记为导出?

    是的,这是正确的,COM就是这样做的,DLL只公开了4个方法,其中一个返回到类工厂,它的所有成员都是纯虚函数。

    相反,如果希望调用静态定义的成员函数,是否需要导出类声明?

    不,只是导出静态成员函数。

    【讨论】:

      【解决方案2】:

      仅当函数/类的所有定义都包含在头文件中时才需要。 它不依赖于虚拟性。

      因此,如果您不导出所有类,客户端代码可以使用它,只要它在 cpp 文件中没有任何公共或受保护的函数定义。

      您也可以只声明要导出的特定成员函数而不是整个类,方法是在函数声明中而不是在类名声明中使用 __declspec。

      【讨论】:

      • "它不依赖于虚拟性" 不是吗?如果一个函数是虚拟的,那么它是通过 vptr/vtable 调用的。例如,COM 对象不会导出每个(甚至任何)方法实现。
      • 是的,但是 COM 对象会导出 vptr 表本身。
      • 不,他们没有:相反,COM 对象本身包含一个指向它自己的 vtable 的指针(因此任何拥有 COM 对象实例的人都不需要链接到 COM 对象的导出函数,或者甚至链接到它的 vtable)。
      【解决方案3】:

      我的看法是否正确……

      是的,我想是的,但是:

      • 你应该测试一下(我现在不能)

      • 您可能要小心使用内联方法:因为如果您稍后更改它们,那么您应该重新构建依赖于(已构建)该类的所有其他组件(即 DLL 不再适用- 绝缘或自包含...内联方法在单个 DLL 中是可以的,但如果在 DLL 的导出接口中使用,则有利于一种“DLL 地狱”。

      相反,如果希望调用静态定义的成员函数,是否需要导出类声明?

      如果不是整个类,您至少需要导出那些单独的静态方法。

      【讨论】:

        【解决方案4】:

        C++ 名称修饰是编写交叉编译器模块成功的负担, 只需将要公开的类声明为只包含虚函数的接口即可。 带有虚函数的类的布局可能是“标准化的”,想想 COM。

        【讨论】:

          猜你喜欢
          • 2021-11-06
          • 2015-10-24
          • 1970-01-01
          • 1970-01-01
          • 2016-10-21
          • 2023-02-01
          • 1970-01-01
          • 2010-10-15
          • 1970-01-01
          相关资源
          最近更新 更多