简体   繁体   English

C++ 等效于 C# 的内部

[英]C++ equivalent of C#'s internal

I am trying to backport some code from C# to C++ to get around an annoying problem, and what like to ask if anyone knows what the equivalent of C#'s 'internal' would be in C++.我正在尝试将一些代码从 C# 向后移植到 C++ 以解决一个烦人的问题,并且想问是否有人知道 C# 的“内部”在 C++ 中的等价物是什么。

Here's an example of the it in use:这是使用中的示例:

internal int InternalArray__ICollection_get_Count ()
        {
            return Length;
        }

There is no direct equivalent of internal in C++. C++ 中没有直接等效的internal Apart from public / protected / private the only other access control mechanism is friend , a mechanism by which can allow specific classes access to all members of your own class.除了public / protected / private唯一的其他访问控制机制是friend ,一种允许特定类访问您自己类的所有成员的机制。

It could therefore be used as an internal -like access control mechanism, with the big difference being that:因此,它可以用作类似internal的访问控制机制,最大的区别在于:

  • you have to explicitly declare friend classes one by one你必须一一明确地声明friend
  • friend classes have access to all members without exception; friend类无一例外地可以访问所有成员; this is an extremely high level of access and can introduce tight coupling (which is the reason why the customary reflex reaction to friend is "do you really need that?")这是一种极高级别的访问,并且可以引入紧密耦合(这就是为什么对friend的习惯性反射反应是“你真的需要那个吗?”的原因)

See also When should you use 'friend' in C++?另请参阅何时应该在 C++ 中使用“朋友”?

If your idea is to isolate whole modules from one another, you could try keeping two sets of header files – one with the "public" methods, another with the "internal" ones.如果您的想法是将整个模块彼此隔离,您可以尝试保留两组头文件——一组使用“公共”方法,另一组使用“内部”方法。 I'm not sure how to avoid duplication at this point;我不确定此时如何避免重复; AFAIK a class may only be declared once in a compilation unit, and both the public and internal header need a complete definition of a class. AFAIK 一个类只能在编译单元中声明一次,并且公共和内部头都需要一个完整的类定义。 One, admittedly very clunky way would be to have partial files like _Foo.public.h and _Foo.internal.h that only contain method declarations, and the "real" header files include one or both of those into the class declaration body:一种,公认非常笨拙的方法是拥有像_Foo.public.h_Foo.internal.h这样的部分文件,它们只包含方法声明,而“真正的”头文件将其中一个或两个都包含在类声明主体中:

Foo.public.h foo.public.h

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

Foo.internal.h内部文件

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

Source files would refer to the internal headers of their own module, but to the public ones of their dependencies.源文件会引用它们自己模块的内部头文件,但会引用它们的依赖项的公共头文件。 It should be possible to tweak the project layout and build scripts to make this reasonably transparent.应该可以调整项目布局并构建脚本以使其合理透明。 (Eg setting up the include paths to the correct directories for each module.) (例如,为每个模块设置正确目录的包含路径。)

This merely hides the "internal" members instead of implementing actual access control, and thus assumes that modules are compiled separately and treated as binary dependencies.这只是隐藏了“内部”成员而不是实现实际的访问控制,因此假设模块是单独编译的并被视为二进制依赖项。 If you handle dependencies by including them in the source tree and compiling everything at once, you need to be able to build them anyway, and the internal method declarations might still be present in the build.如果您通过将依赖项包含在源代码树中并一次编译所有内容来处理依赖项,则无论如何您都需要能够构建它们,并且内部方法声明可能仍然存在于构建中。

For anyone still interested, I think there's a macro solution.对于仍然感兴趣的任何人,我认为有一个宏解决方案。 Usually when creating an API I define a "BUILDDLL" macro in the API project's settings that is used to define DLL export/import like such:通常在创建 API 时,我会在 API 项目的设置中定义一个“BUILDDLL”宏,用于定义 DLL 导出/导入,如下所示:

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

So I also use it to define an INTERNAL macro:所以我也用它来定义一个 INTERNAL 宏:

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

BUILDDLL is defined in the DLL project's settings (in VS, properties->C\\C++->preprocessor->preprocessor definitions), but not the consumer project's settings. BUILDDLL 在 DLL 项目的设置中定义(在 VS 中,属性->C\\C++->预处理器->预处理器定义),而不是使用者项目的设置。 So for the consumer, the macro is replaced with "private", but it's "public" within the DLL project.因此,对于使用者,宏被替换为“私有”,但它在 DLL 项目中是“公共的”。 You'd use it just like any other access modifier:您可以像使用任何其他访问修饰符一样使用它:

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

It's not a perfect solution (you can't use it with member functions whose definitions appear in header files, for example, and there's nothing stopping the end user from overriding it), but it seems to work without error.这不是一个完美的解决方案(例如,您不能将其与定义出现在头文件中的成员函数一起使用,并且没有什么可以阻止最终用户覆盖它),但它似乎可以正常工作。 I think it fits as one of the "good" uses for macros, and it's pretty clear for an outsider looking at the code (who is familiar with the C# keyword) what it means.我认为它适合作为宏的“好”用途之一,对于查看代码的局外人(熟悉 C# 关键字的人)来说,它的含义非常清楚。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM