创建虚函数的纯虚函数是否危险?
Is it dangerous to create pure virtual function of a virtual function?
让我们假设我们有一个摘要 class NonEditableSuperBase
我们从中创建另一个摘要 class MyBase
.
第一个classNonEditableSuperBase
有虚函数(非纯虚)。但是,我想强制如果有人创建了一个派生自 MyBase
的 class,he/she 必须提供上述函数的实现。
因此,我的想法是在MyBase
中将函数定义为纯虚函数。
我的问题:鉴于它在 NonEditableSuperBase
中只是虚拟的,这是个坏主意吗?
示例:
//NonEditableSuperBase.h
class NonEditableSuperBase
{
...
public:
virtual int someMethod(); //It has an implementation, suppose {return 42;}
};
//MyBase.h
class MyBase: public NonEditableSuperBase
{
public:
explicit MyBase();
virtual ~MyBase() = default;
virtual int someMethod() = 0; //I make it pure virtual
};
//MyBase.cpp
MyBase::MyBase() : NonEditableSuperBase() { }
//Now someone creates a derived class from MyBase.
class SuperDerived : public MyBase
{
public:
explicit SuperDerived();
int someMethod(); //The user must create an implementation of the function
};
更新:
例如,在我的例子中,我想从 Qt 框架的 QAbstractTableModel class 创建一些派生的 classes。为了重用一些代码,我想创建一个中间摘要 class.
QAbstractTableModel <- MyAbstractModel <- MyModelA (or MyModelB ... etc).
但是,我想确保模型(MyModelA、MyModelB)重新实现 QAbstractTableModel 的一些虚函数(如 ::index() 函数),因为 MyAbstractModel 的一些附加方法需要特定的实现的引物功能。
§ 10.4 says:
5 [ Note: An abstract class can be derived from a class that is not abstract, and a pure virtual function may
override a virtual function which is not pure. —end note ]
所以完全有可能做到这一点。
用例示例:
你可以有一个基本类型,它被实现为具体类型 (base class)。现在,对于子类型,我们可能需要进一步的附加信息。所以,我们可以有一个抽象的中间对象来满足我们的需求。
[我假设 MyBase 的目的是公开派生自 NonEditableSuperBase,这不是问题中的代码示例实际做的事情。]
它本身似乎并不危险,但考虑到像从 MyBase 派生的 SuperDerived 这样的 class 可以明确选择使用 NonEditableSuperBase 实现。
class SuperDerived : public MyBase {
public:
using NonEditableSuperBase::someMethod;
// Or, explicitly:
// int someMethod() override { return NonEditableSuperBase::someMethod(); }
};
这满足了 MyBase 强加的纯虚拟要求,但表现得就像 MyBase 没有该要求一样。你已经让 SuperDerived 的作者做了一些事情,但你实际上并没有阻止他们使用最终基础 class 的实现。
让我们假设我们有一个摘要 class NonEditableSuperBase
我们从中创建另一个摘要 class MyBase
.
第一个classNonEditableSuperBase
有虚函数(非纯虚)。但是,我想强制如果有人创建了一个派生自 MyBase
的 class,he/she 必须提供上述函数的实现。
因此,我的想法是在MyBase
中将函数定义为纯虚函数。
我的问题:鉴于它在 NonEditableSuperBase
中只是虚拟的,这是个坏主意吗?
示例:
//NonEditableSuperBase.h
class NonEditableSuperBase
{
...
public:
virtual int someMethod(); //It has an implementation, suppose {return 42;}
};
//MyBase.h
class MyBase: public NonEditableSuperBase
{
public:
explicit MyBase();
virtual ~MyBase() = default;
virtual int someMethod() = 0; //I make it pure virtual
};
//MyBase.cpp
MyBase::MyBase() : NonEditableSuperBase() { }
//Now someone creates a derived class from MyBase.
class SuperDerived : public MyBase
{
public:
explicit SuperDerived();
int someMethod(); //The user must create an implementation of the function
};
更新: 例如,在我的例子中,我想从 Qt 框架的 QAbstractTableModel class 创建一些派生的 classes。为了重用一些代码,我想创建一个中间摘要 class.
QAbstractTableModel <- MyAbstractModel <- MyModelA (or MyModelB ... etc).
但是,我想确保模型(MyModelA、MyModelB)重新实现 QAbstractTableModel 的一些虚函数(如 ::index() 函数),因为 MyAbstractModel 的一些附加方法需要特定的实现的引物功能。
§ 10.4 says:
5 [ Note: An abstract class can be derived from a class that is not abstract, and a pure virtual function may override a virtual function which is not pure. —end note ]
所以完全有可能做到这一点。
用例示例:
你可以有一个基本类型,它被实现为具体类型 (base class)。现在,对于子类型,我们可能需要进一步的附加信息。所以,我们可以有一个抽象的中间对象来满足我们的需求。
[我假设 MyBase 的目的是公开派生自 NonEditableSuperBase,这不是问题中的代码示例实际做的事情。]
它本身似乎并不危险,但考虑到像从 MyBase 派生的 SuperDerived 这样的 class 可以明确选择使用 NonEditableSuperBase 实现。
class SuperDerived : public MyBase {
public:
using NonEditableSuperBase::someMethod;
// Or, explicitly:
// int someMethod() override { return NonEditableSuperBase::someMethod(); }
};
这满足了 MyBase 强加的纯虚拟要求,但表现得就像 MyBase 没有该要求一样。你已经让 SuperDerived 的作者做了一些事情,但你实际上并没有阻止他们使用最终基础 class 的实现。