受保护的构造函数,使基类不可实例化
Protected constructor to make base class not instantiable
如果我想避免基类构造函数的实例,那么保护基类构造函数是好的做法吗?我知道我也可以有一个纯粹的虚拟虚拟方法,但这似乎很奇怪......
请考虑以下代码:
#include <iostream>
using std::cout;
using std::endl;
class A
{
protected:
A(){};
public:
virtual void foo(){cout << "An";};
};
class B : public A
{
public:
void foo(){cout << "Bn";}
};
int main()
{
B b;
b.foo();
A *pa = new B;
pa->foo();
// this does (and should) not compile:
//A a;
//a.foo();
return 0;
}
是否有我没有看到的缺点或副作用?
通常的做法是保护基类构造函数。当您的基类中有一个纯虚函数时,这不是必需的,因为您将无法实例化它。
但是,在基类中定义非纯虚函数不被认为是好的做法,但在很大程度上取决于您的用例并且不会造成伤害。
没有任何缺点或副作用。使用受保护的构造函数,您只需告诉其他开发人员您的类仅用作基。
你想要实现的通常是通过析构函数而不是构造函数完成的,因为你可以用这个函数来引导你需要的行为,而不必用你编写的每个新构造函数来处理它。这是一种常见的编码风格/指南,用于
- 如果要
- 允许类的实例,请将析构函数设为公共。 通常,这些类不是要继承的。
- 如果要在多态上下文中使用和删除类,但又不想允许类的实例,请将析构函数设置为纯虚拟和公共。换句话说,对于以多态方式删除的基类。
- 如果不想允许类的实例并且不想以多态方式删除其派生,请将析构函数设为非虚拟且受保护。通常,您根本不想多态地使用它们,即它们没有虚函数。
您选择后两者中的哪一个是设计决策,无法从您的问题中回答。
它按照你的要求去做。
但是,我不确定您从中获得什么。有人可以写
struct B : A {
// Just to workaround limitation imposed by A's author
};
通常不是在基类中添加无意义的纯虚拟函数......而是存在纯虚函数,在基本级别无法提供有意义的实现,这就是为什么它们最终成为纯虚拟函数的原因。
无法实例化该类是一个不错的额外属性。
使析构函数成为纯虚拟的。每个类都有一个析构函数,基类通常应该有一个虚拟析构函数,因此您不会添加无用的虚拟函数。
请注意,纯虚拟析构函数必须具有函数体。
class AbstractBase
{
public:
virtual ~AbstractBase() = 0;
};
inline AbstractBase::~AbstractBase() {}
如果不希望将析构函数正文放在头文件中,请将其放在源文件中并删除内联关键字。
相关文章:
- C++初始化基类
- 设计一个只能由特定类实例化的类(如果可能的话,通过make_unique)
- 无法使用 SWIG 在 Python 中实例化C++类(获取属性错误)
- ATL::CComContainedObject<contained>: C2259 无法实例化抽象类
- 没有实例的基类?
- C++17 使用驱动类常量作为基类构造函数的参数来初始化基类构造函数
- 从多个模板化基类派生时出现"隐藏重载的虚函数"警告
- 为什么派生类的实例从基类调用方法?
- 尝试实例化模板类的对象时出现"No Matching Constructor"错误
- 如何使用其中一个具体类实例化抽象类?
- 我是否需要在虚拟继承类的构造函数中初始化基类以解决菱形继承问题?
- 在实例化封闭类模板之后,我们可以声明模板类成员的部分专用化吗
- 使用派生类实例化基类,而不在对象定义中使用指针
- 为什么可以从实例化基类对象的投射指针调用非静态派生类方法
- C++ - 实例化派生类并使用基类的构造函数
- 是否可以使用对派生类实例的基类引用初始化派生类引用
- 从基类模板化列表中实例化子类对象
- 实例化派生类对象,该对象的基类ctor是私有的
- 实例化基类-Win32对话框类
- 转换基指针时出错:“不能实例化抽象类”