C ++:使类及其某些数据成员仅在命名空间中可用

Posted

技术标签:

【中文标题】C ++:使类及其某些数据成员仅在命名空间中可用【英文标题】:C++: Make class and some of its data members only available in namespace 【发布时间】:2018-04-13 00:30:49 【问题描述】:

是否可以让一个类只在命名空间内可用?或者是否有另一种方法,而不使用命名空间? 我正在创建一个框架,并且不希望该框架的用户可以访问所有类,而只能访问特定的类。

但是:用户应该能够访问所有定义以创建指向这些类的指针变量。此外,他不应该能够访问这些类的所有数据成员,但我希望我的框架能够访问所有数据成员。

这可能吗?

示例(仅作为对我请求的解释):

/* T2DApp.h */
namespace T2D 
    // I don't want the user to be able to create an instance of this class (only pointer vars), but the framework should be able to.
    class T2DApp 
    public:
        // constructor, destructor... //

        SDL_Window*  Window;
        SDL_Surface* Surface;

        bool Running = false;
    


/* T2D.h */
#include "T2DApp.h"

void init();

/* T2D.cpp */
#include "T2D.h"

void init() 
    T2D::T2DApp app;       // function in framework is able to create new instance of T2DApp.
    app.Window.Whatever(); // every data member should be available to framework directly without getter methods.
    app.Window.Whatever(); // dito
    app.Running = true;    // dito


/* [cpp of user] */
#include "T2D.h"

void main(etc.) 
    ...
    T2D::T2DApp app;    // User shouldn't be able to create an instance of T2DApp
    T2D::T2DApp* p_app; // but he should still be able to "see" the class definition for creating pointers
    ...
    p_app.Running = true;     // User shouldn't be able to access this data member
    p_app.Window.Whatever();  // But he should be able to access the other data members
    p_app.Surface.Whatever(); // dito
    ...

提前非常感谢你:)

【问题讨论】:

T2DApp 周围有一个namespace detailnamespace internal 是很常见的,并且文档中说“命名空间detail / internal 内的任何内容都不能被用户” 【参考方案1】:

Pimpl idiom 是可能的:

“指向实现的指针”或“pImpl”是一种 C++ 编程技术,它通过将类的实现细节放在一个单独的类中,从其对象表示中删除它们,通过一个不透明的指针访问它们。

【讨论】:

啊,我记得我曾经读过这个技术;但是真的不建议使用这个成语吗? @TobbeWidner 这种技术的代价是在构造和通过指针间接寻址期间分配额外的内存。这两个问题都可以通过使用std::aligned_storage 而不是指针来消除,但是在这种情况下,实现类的大小必须在标头中公开。例如。 github.com/sqjk/pimpl_ptr 写一个包装类是否更简洁,我在其中定义了额外的方法和数据成员,它们只引用了类T2DApp的那些成员,用户需要访问?还是说这是一个相对较大的资源杀手? @TobbeWidner 如果我理解正确的话,包装类中的每个引用都将采用指针的大小。 没错。我知道它也不是很“干净”。我想我还是得试试 pimpl xD

以上是关于C ++:使类及其某些数据成员仅在命名空间中可用的主要内容,如果未能解决你的问题,请参考以下文章

总结

第13条:使类和成员的可访问性最小化

如何使类的成员只能在任何包的子类中访问?

如何在Asp .Net Web API中的请求的整个生命周期中使类对象可用?

C++--面向对象的基本概念

使类和成员的可访问性最小化