禁止转换为父级,但公开父级接口(设计问题)
Posted
技术标签:
【中文标题】禁止转换为父级,但公开父级接口(设计问题)【英文标题】:Forbid conversions to parent, but expose publicly parent's interface (design issue) 【发布时间】:2018-11-06 19:05:12 【问题描述】:我不确定如何以最优雅的方式实现(用 C++ 表示)以下问题。假设我们有一个库提供类PerfectCounter
具有丰富的非虚拟接口。我想实现继承自PerfectCounter
的类DisturbedCounter
。新类应公开与其父级相同的接口,例如允许为两个类的实例对调用一些运算符(<
、>
、==
等)。此外,我想禁止两个类之间的转换(两种方式)。
DisturbedCounter
可以从PerfectCounter
私有继承。它将阻止从DisturbedCounter
到PerfectCounter
的转换。但是,我必须在 DisturbedCounter
中明确地将 99% 的 PerfectCounter
API 重新声明为“公共”。这意味着未来需要大量的编写和维护。
有没有更好的方法来解决这个问题?
我可以使用 C++17。
【问题讨论】:
如果这些函数是虚拟的,为什么不希望转换为父函数?如果它们不是虚拟的,那么覆盖它们似乎是个坏主意。 @SergeyAPerfectCounter
有非虚拟界面,之前没提过。
好问题,唉,在今天的 C++ 中没有答案。我们希望有using A::* except blargh;
也许有一天。
@n.m.确实,这正是我正在寻找的东西。我害羞地希望有一个简洁的 C++1* 结构可以解决我的问题。
【参考方案1】:
您可以让 DisturbedCounter 私下从 PerfectCounter 继承。那么它们之间的转换将是不允许的(因为在这种情况下 DisturbedCounter 不是 PerfectCounter,它只是根据一个实现)。
然后您可以使用using
指令公开您希望在 DisturbedCounter 中公开使用的 PerfectCounters 接口部分,并添加您想要的任何比较运算符的实现。
当然还有其他方法可以解决,但这至少是您要考虑的一种。
【讨论】:
这是我在第二段中描述的方法(可能我不够清楚)。这是一个相当乏味的解决方案,因为我必须为 PerfectCounter 中的每个方法使用using
。
@Goofy 我现在看到了(重读时)——我想我读起来很烂。反正;是的,很乏味,但仍然是我能想到的解决这个特定问题的最直接的方法。【参考方案2】:
我不确定这是否正是您需要的,因为 DisturbedCounter 不是从 PerfectCounter 继承的。它使用CRTP 来避免转换,并且它应该允许您只执行每个方法一次(除了那些真正应该不同的方法)并且您不需要来自基类的using
。我不擅长模板,所以这可能会被某人撕开,但是o.t.o.h.,如果不是,它可能会给你一些想法,它可能是一些可以构建的东西。缺少很多样板。
#include <iostream>
template<class T>
struct Common
protected:
double m_count;
public:
Common() : m_count(0)
Common& operator=(const Common& rhs)
m_count = rhs.m_count;
return *this;
operator double () const return m_count;
double get() const return m_count;
;
// type specific implementation
struct PerfectCounter : Common<PerfectCounter>
void count()
m_count += 10.0;
;
// type specific implementation
struct DisturbedCounter : Common<DisturbedCounter>
void count()
m_count += 9.9;
;
int main()
PerfectCounter a;
a.count();
DisturbedCounter b;
b.count();
//a = b; // error
//b = a; // error
if( a>b ) std::cout << "a>b\n";
std::cout << a << " " << b << "\n";
输出
a>b
10 9.9
【讨论】:
以上是关于禁止转换为父级,但公开父级接口(设计问题)的主要内容,如果未能解决你的问题,请参考以下文章