c++ - 我应该避免多重实现继承吗?
问题描述
我想为可以从外部方法/类访问的类的不同属性定义接口。
我使用多重实现继承(=从与接口继承相反的具体类继承),这被认为是一种不好的做法(此处的第 3 点)。
我使用继承来重用代码。正如这里所说,最好使用组合而不是继承来重用代码。但是对于组合,我所有的
MyObj1,MyObj2,...,MyObj1000
人都会有相同的 get 和 set 方法,而我很少需要重新实现它们。
这种情况是否完美地说明了代码重用的多重实现继承良好或这段代码完全错误的情况,我应该使用一些巧妙的语法/模式来避免这种设计?我问这个问题是因为我相信后者。
#include <string>
#include <iostream>
// interface of object with name
class BaseName {
public:
virtual void setName(const std::string& val) { name = val; }
virtual std::string getName() const { return name; }
private:
std::string name;
};
// user of interface of objects with name
void nameUser(BaseName* b) {
std::cout << b->getName() << std::endl;
}
// interface of object with id
class BaseID {
public:
virtual void setID(int val) { id = val; }
virtual int getID() const { return id; }
private:
int id = 0;
};
// user of interface of objects with id
void idUser(BaseID* b) {
std::cout << b->getID() << std::endl;
}
class MyObj1 : public BaseID, public BaseName {
public:
void setName(const std::string& val) override {
/* update internal state that depends on name. this is why "virtual" is required */
BaseName::setName(val);
}
/* methods and fields specific to MyObj1 */
};
// MyObj2,...,MyObj999
class MyObj1000 : public BaseID, public BaseName {
public:
/* methods and fields specific to MyObj1000 */
};
int main() {
MyObj1 o1;
o1.setName("xxx");
o1.setID(18);
MyObj1000 o2;
o2.setName("yyy");
o2.setID(-738);
nameUser(&o1);
nameUser(&o2);
idUser(&o1);
idUser(&o2);
}
解决方案
如果您的派生类是基类,您应该只继承,也就是说,它在您的系统中作为它继承的类是有意义的。
也就是说,多重继承在 C++ 中非常好。一个类可以有多个 IS-A 基类。使用所谓的混合类或接口也是一种很好的做法。类为类添加一些功能而不会过多地打扰类的其余部分。例如继承一个 Serializable 基类。
我会尽量避免的一件事是钻石问题。那就是继承两个或多个类,这些类又继承自同一个基类。例如
class Base { int base; };
class A : public Base { };
class B : public Base { };
class X : public class A, B { };
在这种情况下,很难理解 X.base 是从什么时候来的,而且 A 和 B 很容易对 Base 类进行不同的使用。这将导致难以调试的错误。