使用通用虚函数实现的任意组合实现派生类的正确方法是啥?
Posted
技术标签:
【中文标题】使用通用虚函数实现的任意组合实现派生类的正确方法是啥?【英文标题】:What is the correct way to implement derived classes with arbitrary combinations of common virtual function implementations?使用通用虚函数实现的任意组合实现派生类的正确方法是什么? 【发布时间】:2018-10-30 20:42:20 【问题描述】:在不复制代码的情况下,用不同的通用成员函数实现组合实现一组派生类的正确方法是什么? W
、X
、Y
和 Z
类都派生自类 base
,因为它们需要能够访问基类中的成员变量。
我知道通过钻石继承来做到这一点,但我怀疑有更好的方法。
class base
virtual void f() /* implementation f_0 */
virtual void g() /* implementation g_0 */
virtual void h() /* implementation h_0 */
;
class W : public base
void g() override /* implementation g_1 */
;
class X : public base
void g() override /* implementation g_1 */
void h() override /* implementation h_1 */
;
class Y : public base
void f() override /* implementation f_1 */
void h() override /* implementation h_1 */
;
class Z : public base
void f() override /* implementation f_1 */
void h() override /* implementation h_2 */
;
【问题讨论】:
虚函数必须是纯虚函数吗?*_0
实现是否只是函数的默认实现?
感谢您的建议。我尝试更新示例以改进它,但我想它可能会因反对票而关闭。
【参考方案1】:
使用具有默认实现的中间类:
class base
public:
virtual ~base() = default;
virtual void f() = 0;
virtual void g() = 0;
virtual void h() = 0;
;
class derived : public base
void f() override /* implementation f_0 */
void g() override /* implementation g_0 */
void h() override /* implementation h_0 */
;
class X : public derived
void g() override /* implementation g_1 */
;
class Y : public derived
void f() override /* implementation f_1 */
;
class Z : public derived
void h() override /* implementation h_1 */
;
【讨论】:
感谢您的建议。我尝试更新示例以改进它,但我想这个问题可能会因反对票而关闭。【参考方案2】:Marc Gregoire 在Professional C++ 的第 10 章中讨论了这个话题。
这是一种使用钻石继承的方法。
#include <iostream>
using namespace std;
struct base
virtual void f() cout << "f_0\n"; /* implementation f_0 */
virtual void g() cout << "g_0\n"; /* implementation g_0 */
virtual void h() cout << "h_0\n"; /* implementation h_0 */
;
struct f_1 : public virtual base
void f() override cout << "f_1\n"; /* implementation f_1 */
;
struct g_1 : public virtual base
void g() override cout << "g_1\n"; /* implementation g_1 */
;
struct h_1 : public virtual base
void h() override cout << "h_1\n"; /* implementation h_1 */
;
struct h_2 : public virtual base
void h() override cout << "h_2\n"; /* implementation h_2 */
;
struct W : public g_1
// void g() override /* implementation g_1 */
;
struct X : public g_1, h_1
// void g() override /* implementation g_1 */
// void h() override /* implementation h_1 */
;
struct Y : public f_1, h_1
// void f() override /* implementation f_1 */
// void h() override /* implementation h_1 */
;
struct Z : public f_1, h_2
// void f() override /* implementation f_1 */
// void h() override /* implementation h_2 */
;
int main()
cout << "\nW\n";
W w;
w.f();
w.g();
w.h();
cout << "\nX\n";
X x;
x.f();
x.g();
x.h();
cout << "\nY\n";
Y y;
y.f();
y.g();
y.h();
cout << "\nZ\n";
Z z;
z.f();
z.g();
z.h();
输出:
W
f_0
g_1
h_0
X
f_0
g_1
h_1
Y
f_1
g_0
h_1
Z
f_1
g_0
h_2
【讨论】:
以上是关于使用通用虚函数实现的任意组合实现派生类的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章