25

我正在尝试将一些代码从 C# 反向移植到 C++ 以解决一个烦人的问题,并且想问是否有人知道 C# 的“内部”在 C++ 中的等价物是什么。

这是一个使用它的例子:

internal int InternalArray__ICollection_get_Count ()
        {
            return Length;
        }
4

3 回答 3

28

internal在 C++中没有直接的等价物。除了public//唯一的其他访问控制机制是protected,一种可以允许特定类访问您自己类的所有成员的机制。privatefriend

因此,它可以用作类似的internal访问控制机制,最大的区别在于:

  • 您必须friend一个一个显式声明类
  • friend类无一例外地可以访问所有成员;这是一个极高级别的访问,并且可以引入紧密耦合(这就是为什么习惯性的反射反应friend是“你真的需要那个吗?”)

另请参阅何时应该在 C++ 中使用“朋友”?

于 2012-12-05T11:56:51.703 回答
5

如果您的想法是将整个模块彼此隔离,您可以尝试保留两组头文件——一组使用“公共”方法,另一组使用“内部”方法。目前我不确定如何避免重复;AFAIK一个类只能在编译单元中声明一次,公共和内部头都需要一个完整的类定义。一种,公认的非常笨拙的方法是让部分文件像_Foo.public.h并且_Foo.internal.h只包含方法声明,而“真正的”头文件将其中一个或两个包含在类声明主体中:

Foo.public.h

class Foo {
    #include "_foo.public.h"
}

Foo.internal.h

class Foo {
    #include "_foo.internal.h"
}

源文件将引用它们自己模块的内部头文件,但指向其依赖项的公共头文件。应该可以调整项目布局并构建脚本以使其合理透明。(例如,为每个模块设置正确目录的包含路径。)

这只是隐藏了“内部”成员,而不是实现实际的访问控制,因此假设模块是单独编译的并被视为二进制依赖项。如果您通过将依赖项包含在源代码树中并一次编译所有内容来处理依赖项,那么无论如何您都需要能够构建它们,并且内部方法声明可能仍然存在于构建中。

于 2012-12-05T12:27:52.160 回答
0

对于任何仍然感兴趣的人,我认为有一个宏观解决方案。通常在创建 API 时,我会在 API 项目的设置中定义一个“BUILDDLL”宏,用于定义 DLL 导出/导入,如下所示:

#ifdef BUILDDLL
    #define DLL __declspec(dllexport)
#else
    #define DLL __declspec(dllimport)
#endif

所以我也用它来定义一个 INTERNAL 宏:

#ifdef BUILDDLL
    #define INTERNAL public
#else
    #define INTERNAL private
#endif

BUILDDLL 在 DLL 项目的设置中定义(在 VS 中,属性->C\C++->预处理器->预处理器定义),而不是使用者项目的设置。所以对于消费者来说,宏被替换为“私有”,但它在 DLL 项目中是“公共的”。您可以像使用任何其他访问修饰符一样使用它:

class DLL Foo
{
public:
    int public_thing;
INTERNAL:
    int internal_thing;
};

这不是一个完美的解决方案(例如,您不能将其与定义出现在头文件中的成员函数一起使用,并且没有什么可以阻止最终用户覆盖它),但它似乎可以正常工作。我认为它适合作为宏的“好”用途之一,对于查看代码的局外人(熟悉 C# 关键字)来说,它的含义非常清楚。

于 2021-05-12T19:57:47.623 回答