强制派生 class 覆盖一组虚函数中的一个
Force a derived class to override one of a set of virtual functions
给定一个具有一些虚函数的基 class,有人能想出一种方法来强制派生的 class 在编译时恰好覆盖一组虚函数中的一个吗?还是实现相同目标的 class 层次结构的替代表述?
在代码中:
struct Base
{
// Some imaginary syntax to indicate the following are a "pure override set"
// [
virtual void function1(int) = 0;
virtual void function2(float) = 0;
// ...
// ]
};
struct Derived1 : Base {}; // ERROR not implemented
struct Derived2 : Base { void function1(int) override; }; // OK
struct Derived3 : Base { void function2(float) override; }; // OK
struct Derived4 : Base // ERROR too many implemented
{
void function1(int) override;
void function2(float) override;
};
我不确定我是否真的有这方面的实际用例,但当我实现一些松散地遵循这种模式的东西时,我想到了这一点,并且认为这是一个值得思考的有趣问题,如果没有别的。
如果您不重写所有抽象虚拟方法,您的 类 将保持抽象。如果要实例化对象,则必须执行所有这些操作。
不,但你可以伪造它。
Base 有非虚拟的 float 和 int 方法,它们转发到一个纯虚拟的 std 变体。
两个助手 类,一个 int 一个 float,实现 std 变体一,将两种情况转发给纯虚拟 int 或 float 实现。
负责处理'wrong type'案子
Derived 继承自一个或另一个 helper,并且仅实现 int 或 float。
struct Base
{
void function1(int x) { vfunction(x); }
void function2(float x) { vfunction(x); }
virtual void vfunction(std::variant<int,float>) = 0;
};
struct Helper1:Base {
void vfunction(std::variant<int,float> v) final {
if (std::holds_alternative<int>(v))
function1_impl( std::get<int>(v) );
}
virtual void function1_impl(int x) = 0;
};
struct Helper2:Base {
void vfunction(std::variant<int,float> v) final {
if (std::holds_alternative<float>(v))
function2_impl( std::get<float>(v) );
}
virtual void function2_impl(float x) = 0;
};
struct Derived1 : Base {}; // ERROR not implemented
struct Derived2 : Helper1 { void function1_impl(int) override; }; // OK
struct Derived3 : Helper2 { void function2_impl(float) override; }; // OK
这使用 https://en.wikipedia.org/wiki/Non-virtual_interface_pattern -- 接口包含非虚拟方法,可以覆盖其细节以使其行为不同。
如果你害怕人们会覆盖 vfunction
你可以使用私有锁技术,and/or 只需给它起一个像 private_implementation_detail_do_not_implement
这样的名字并相信你的代码审查过程。
Or an alternative formulation of a class hierarchy that achieves the same thing?
一个选择是有一个实现一个功能的中间基础class。
struct Base
{
virtual ~Base() {};
virtual void function(int) = 0;
virtual void function(float) = 0;
};
template <typename T>
struct TBase : Base
{
virtual void function(T) override {}
};
struct Derived1 : Base {};
struct Derived2 : TBase<float> { void function(int) override {} };
struct Derived3 : TBase<int> { void function(float) override {} };
int main()
{
Derived1 d1; // ERROR. Virtual functions are not implemented
Derived2 d2; // OK.
Derived3 d3; // OK.
}
请注意,函数在此方法中被命名为 function
,而不是 function1
和 function2
。
给定一个具有一些虚函数的基 class,有人能想出一种方法来强制派生的 class 在编译时恰好覆盖一组虚函数中的一个吗?还是实现相同目标的 class 层次结构的替代表述?
在代码中:
struct Base
{
// Some imaginary syntax to indicate the following are a "pure override set"
// [
virtual void function1(int) = 0;
virtual void function2(float) = 0;
// ...
// ]
};
struct Derived1 : Base {}; // ERROR not implemented
struct Derived2 : Base { void function1(int) override; }; // OK
struct Derived3 : Base { void function2(float) override; }; // OK
struct Derived4 : Base // ERROR too many implemented
{
void function1(int) override;
void function2(float) override;
};
我不确定我是否真的有这方面的实际用例,但当我实现一些松散地遵循这种模式的东西时,我想到了这一点,并且认为这是一个值得思考的有趣问题,如果没有别的。
如果您不重写所有抽象虚拟方法,您的 类 将保持抽象。如果要实例化对象,则必须执行所有这些操作。
不,但你可以伪造它。
Base 有非虚拟的 float 和 int 方法,它们转发到一个纯虚拟的 std 变体。
两个助手 类,一个 int 一个 float,实现 std 变体一,将两种情况转发给纯虚拟 int 或 float 实现。
负责处理'wrong type'案子
Derived 继承自一个或另一个 helper,并且仅实现 int 或 float。
struct Base
{
void function1(int x) { vfunction(x); }
void function2(float x) { vfunction(x); }
virtual void vfunction(std::variant<int,float>) = 0;
};
struct Helper1:Base {
void vfunction(std::variant<int,float> v) final {
if (std::holds_alternative<int>(v))
function1_impl( std::get<int>(v) );
}
virtual void function1_impl(int x) = 0;
};
struct Helper2:Base {
void vfunction(std::variant<int,float> v) final {
if (std::holds_alternative<float>(v))
function2_impl( std::get<float>(v) );
}
virtual void function2_impl(float x) = 0;
};
struct Derived1 : Base {}; // ERROR not implemented
struct Derived2 : Helper1 { void function1_impl(int) override; }; // OK
struct Derived3 : Helper2 { void function2_impl(float) override; }; // OK
这使用 https://en.wikipedia.org/wiki/Non-virtual_interface_pattern -- 接口包含非虚拟方法,可以覆盖其细节以使其行为不同。
如果你害怕人们会覆盖 vfunction
你可以使用私有锁技术,and/or 只需给它起一个像 private_implementation_detail_do_not_implement
这样的名字并相信你的代码审查过程。
Or an alternative formulation of a class hierarchy that achieves the same thing?
一个选择是有一个实现一个功能的中间基础class。
struct Base
{
virtual ~Base() {};
virtual void function(int) = 0;
virtual void function(float) = 0;
};
template <typename T>
struct TBase : Base
{
virtual void function(T) override {}
};
struct Derived1 : Base {};
struct Derived2 : TBase<float> { void function(int) override {} };
struct Derived3 : TBase<int> { void function(float) override {} };
int main()
{
Derived1 d1; // ERROR. Virtual functions are not implemented
Derived2 d2; // OK.
Derived3 d3; // OK.
}
请注意,函数在此方法中被命名为 function
,而不是 function1
和 function2
。