通过模板类继承满足纯虚函数合约
Satisfying pure virtual function contract with template class inheritance
如果之前已经回答过,请道歉;我搜索了Stack Overflow,但找不到类似的东西。我有一种感觉,我所要求的是不可能的,但我相信一定有办法实现它。
我正在使用一个基类,其中包含许多聚集成逻辑相关组的纯虚函数。理想情况下,我不想简单地在我的派生类中实现这些函数,而是将这些函数分组到处理相关功能的类中,然后将它们拉入我的派生类中。
我尝试使用(下面的简化示例(执行此操作,但收到以下错误:
// The base class - I can't change this
class Base {
public:
virtual void toImplement(double a) = 0;
};
// Implements logically grouped functionality required by the base class
class Implementor {
public:
virtual void toImplement(double a) {}
};
// Concrete derived class, satisfying Base functional requirements by
// (somehow) drawing on the Implementor class functionality.
template <typename Type>
class Derived : public Base, Type {
};
int main() {
Derived<Implementor> a; // Fails
}
此操作失败并显示错误:
error: variable type 'Derived<Implementor>' is an abstract class
Derived<Implementor> a;
^
note: unimplemented pure virtual method 'toImplement' in 'Derived'
virtual void toImplement(double a) = 0;
谁能建议我实现这一目标或类似的东西?主要约束是我无法更改基类。
如果我正确理解了这个问题,你想使用其他类来注入实现的方法。
您只需要将函数调用委托给实现者。下面的代码更通用,因为它可以将许多实现器组合在一起。
注意:由于折叠表达式,它在 C++17 中。但是,您可以通过 C++17 之前的方式轻松实现此功能。
#include <tuple>
#include <iostream>
#include <memory>
struct Base {
virtual void toImplement(double a) = 0;
};
template <class... Impls>
struct Derived : public Base {
virtual void toImplement(double a) override {
do_all(a, std::index_sequence_for<Impls...>{});
}
std::tuple<Impls...> impls;
private:
template<std::size_t... Is>
void do_all(double a, std::index_sequence<Is...>) {
(std::get<Is>(impls).do_(a), ...);
}
};
// test
struct Implementor1 {
void do_(double a) { std::cout << "first impl do: " << a << "n"; }
};
struct Implementor2 {
void do_(double a) { std::cout << "second impl do: " << a << "n"; }
};
int main() {
std::unique_ptr<Base> ptr = std::make_unique<Derived<Implementor1, Implementor2>>();
ptr->toImplement(2.3);
}
如果您必须处理可怕的钻石继承,以下是您的操作方法:
class Base {
public:
virtual void toImplement(double a) = 0;
};
class Implementor : public virtual Base {
public:
virtual void toImplement(double a) {}
};
template <typename Type>
class Derived : public virtual Base, virtual Type {
};
int main() {
Derived<Implementor> a; // Fails
}
你现在拥有它的方式,toImplement
Implementor
与 Base
中意外命名相似的函数无关。
相关文章:
- "error: no matching function for call to"构造函数错误
- 什么时候调用组成单元对象的析构函数
- 继承函数的重载解析
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- C++模板来检查友元函数的存在
- 如何反复调用函数直到满足模拟?
- C++函数,它将数组、谓词和运算符作为参数,并将运算符应用于满足谓词的数组元素
- 通过模板类继承满足纯虚函数合约
- 当满足条件时,是否可以在 GLSL 着色器中回调 C/C++ 函数/代码
- 满足动态条件时退出递归函数
- 如果函数C++中满足条件,则完全停止程序
- 只有在结构实例的构造函数中满足条件时,才能创建该实例
- 如果不满足条件,我应该在成员函数中返回什么?
- 如果条件不满足,调用函数时会出现编译时错误
- 为什么可以在构造函数中使用成员初始化来满足显式构造函数的参数?
- 视觉C++无法正确满足构造函数要求
- 如何在满足某个参数时停止所有函数
- 为什么这个递归函数在基本情况似乎得到满足后继续被调用
- 满足条件后如何终止函数
- 当自动满足多态性和虚函数时,正确的行为是什么?