将抽象类(仅纯虚函数)的继承/派生限制到某个类
Limit inheritance/derivation of an abstract class (only pure virtual functions) to a certain class
给定一个抽象类AbstractParentPrinter
(即具有一个纯虚函数):
class AbstractParentPrinter {
public:
virtual void print() = 0;
};
AbstractPrinter
是AbstractParentPrinter
的一个(抽象)子类:
template<typename T, typename = std::enable_if<std::is_base_of<AbstractPrinterStore, T>::value>>
class AbstractPrinter : public AbstractParentPrinter {
protected:
T& getPrinterStore() {
return printerStore;
}
private:
static T printerStore;
};
template<typename T>
T AbstractPrinter <T>::printerStore;
PrinterA
是AbstractPrinter<PrinterStoreA>
的一个子类。PrinterStoreA
是AbstractPrinterStore
的子类(未显示)。
class PrinterA : public AbstractPrinter<PrinterStoreA> {
public:
void print() {
// Do something with PrinterStoreA and print
// An AbstractPrinterStore here instead would be not sufficient
std::cout << "Printer A has printed!" << std::endl;
}
};
由于AbstractPrinter<T>
(与AbstractParentPrinter
合并)不能存储在std::vector
中,因此我为此目的创建了一个父类AbstractPrinter
。除了AbstractPrinter
之外,如何防止AbstractParentPrinter
的派生?
你可以把最基本类的构造函数设为private,然后把你想从它派生的类设为友类。
class AbstractParentPrinter
{
private: AbstractParentPrinter()
{}
template<typename t> friend class AbstractPrinter;
};
另一种方法是限制类的任何使用(不仅仅是继承),例如使用匿名命名空间或使其成为嵌套类。
====对标题中问题的简单一般答案在这里结束====
在您的情况下,可以考虑更改结构以使用非虚拟接口模式。您将创建一个可以保存在vector中的非模板类,它将拥有一个指向模板化版本之一的指针。这是pImpl模式的一个用法。class AbstractParentPrinter;
class Printer
{
AbstractParentPrinter* pImpl;
public:
void print();
//add some constructor code/declaration to initialise pImpl to the correct template
};
您可以在Printer中嵌套AbstractParentPrinter,或者像上面那样向前声明它。如果嵌套它,可以使用std::unique_ptr,否则将在printer的析构函数中删除它。
class AbstractParentPrinter
{
public: virtual void print() = 0;
};
// insert the template definitions here if you like
void Printer::print()
{
pImpl->print();
}
模板甚至可以放在同一个cpp中(是的,cpp中的模板-通常必须将它们放在头文件中的全部要点是使其他代码可以访问它们,但我假设你的问题的动机是隐藏这些实现细节)
你仍然有你原来的基类和实现print的模板,但是现在你有了一个额外的非抽象的,非模板的Printer类,但是拥有这个类还有其他好处。你的消费代码不需要知道抽象类和模板——它可以有一个Printer的向量,它不需要处理指向Printer的指针,这样可以更容易地管理Printer对象的生命周期。Printer类创建的额外层还可以将调用代码与各种打印类实现中的更改隔离开来。
- 大小虚拟继承中的派生类
- 继承时如何构建派生类的变量?
- 如何使用 C++ 中的继承函数访问派生类中的局部变量
- 派生类是从基类继承 v 指针并仅使用它,还是也有自己的 v 指针?
- "std::shared_from_this"不能由其派生类继承吗?
- 继承的数据如何在派生类中放置(排列)?
- C++具有空派生类对象的继承大小
- C++ 继承:基类中重载 operator+ 的 2 次在派生类中无法正常工作
- 如何调用继承的重载运算符<<并在派生类的输出中添加更多文本?
- 在模板派生类中继承具有类型别名的构造函数
- C++继承从基类指针访问派生类中的非虚拟函数
- C++排除通过派生类中的基类继承的类
- 派生类调用使用非继承成员的继承函数
- 多重继承中的派生类的行为类似于聚合
- 在派生类中具有相同签名但继承为受保护的函数
- 有没有办法调用基类函数,该函数在使用私有继承的派生类中被覆盖?
- 继承:动态派生类成员与静态派生类成员
- SIGSEGV 因为基/派生类的继承问题
- 从多重继承中的派生类函数调用适当的父类函数
- 继承函数是否适用于 C++ 中的基类元素或派生类元素?