防止公众使用用作私人基类的类
Prevent public uses of a class used as a private base class
即使使用 base 类也只能确保"我的"代码只能使用"我的"代码?(如果不用用作基类,我可以将其作为我的一个类的private
或protected
嵌套类)
如果我想指出在我的一个类中使用基类是一个实现细节,我可以使用私人基类:
class Base
{
...
}
class Derived: private Base
{
public:
Derived(...): Base{...} {... };
...
}
对于我使用Base
类的Derived
班级的客户,
#include "Derived.h"
void client() {
Derived d{...};
Base *b = static_cast< Base * >(&d);// error
...
}
但是,请想象Base
类是如此专业,混乱或棘手的使用,以至于我不希望代码的客户将其用作基类或创建该类的对象。从某种意义上说,我希望它是我的某些代码的"私有",因此这样的客户端代码失败了:
#include "Derived.h"
class Client: Base// error wanted here
{
public:
Client(...): Base{...} {...};
...
}
void client()
{
Derived d{...};// OK
Base b{...};// error wanted here
Client c{...};// error wanted here
}
我该怎么做?
实际上,我问我如何才能实现诸如Java的软件包私有类之类的东西,这些类别仅适用于同一"软件包"(模块)中的其他类,但不能被"软件包"外的代码使用。
您可以通过将"私人"实体放入 detail
名称空间中,按照惯例"强制"。许多受欢迎的库(例如Boost)这样做:
namespace detail
{
class Base { /* ... */ };
}
class Derived : private detail::Base
{
/* ... */
};
当将模块标准化时,此问题将得到正确解决,因为您将能够控制哪些实体被导出并且哪些是实施详细信息。
这不能像在Java中直接完成。如果仅是避免混乱的问题,则可以将Base
移入命名空间中,该名称空间被您的代码客户端忽略,例如:
namespace hidden {
class Base {
..
};
}
class Derived : private hidden::Base {
...
};
相反,如果您真的想避免使用Base
的可能性,那么如果您打算将Base
用作多个类的父母(随着时间的推移可能会有所不同),那将是一个很难的故事。您可以给Base
一个private
构造函数,并指出您的每个派生类都是Base
的friend
:
class Hider {
private:
Hider() = delete;
class Base {
..
};
friend class Derived;
};
class Derived : Hider::Base {
..
};
当然,这需要您要从Base
派生的每个新类的手动维护。
如果您想100%执行它,并且不喜欢"请不要使用以'_'开头的东西"的Python方法,那么我相信这是您的端口通话:
class Dave;
class MyPrivateBaseClasses {
private:
MyPrivateBaseClasses(); // ensure nothing can use this class
class BaseClassA {};
friend Dave;
};
class Dave : public/private MyPrivateBaseClasses::BaseClassA
{};
肯定 - 这意味着您必须成为所有想要使用它的东西,但它确实为您提供了想要的东西;100%使用基本体的保护人。
- std::具有相同基类的类的变体
- 是否可以初始化不可复制类型的成员变量(或基类)
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 基类中的函数名称解析
- C++初始化基类
- 如何通过派生类函数更改基类中的向量
- 如何定义一个纯抽象基类
- 如何使用基类指针引用派生类成员
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 使用基类指针创建对象时,缺少派生类析构函数
- 如何引用基类的派生类?
- 如果基类包含双指针成员,则派生类的构造函数
- 在模板基类中为继承类中的可选重写生成虚拟方法
- 为什么此派生对象无法访问基类的后递减方法?
- 公开最直接的基类模板名称
- 当基类是依赖类型时,这是一个缺陷吗
- 如何使基类的运算符对基类的可变参数数可见(请参阅下面的代码)?
- 模板基类中的静态变量
- C++ 继承:将子类传递给需要基类的函数并获取子类行为
- 继承和友元函数,从基类访问受保护的成员