条款34:区分接口继承和实现继承
Differentiate between inheritance of interface and inheritance of implementation.
public 继承由两部分组成:函数接口(function interfaces)继承和函数实现(function implementations)继承。而不同类型的函数继承程度也是不一样的:
成员函数的接口总是会被继承;
声明一个 pure virtual 函数的目的是为了让 derived classes 只继承函数接口;
声明简朴的(非纯)impure virtual 函数的目的是让 derived classes 继承该函数的接口和缺省实现;
声明 non-virtual 函数的目的是为了让 derived classes 继承函数的接口及一份强制性的实现;
impure virtual 函数的危险
允许 impure virtual 函数同时指定函数声明和函数缺省行为是有潜在危险的,即在 derived class 未明确表明需要继承的情况下就继承了函数的实现。解决的办法有两个,一是切断“virtual 函数接口”和其“缺省实现”:
class Airplane {
public:
virtual void fly(const Airport& destination) = 0; // 函数接口
...
protected:
void defaultFly(const Airport& destination); // 缺省实现
};
class ModelA: public Airplane {
public:
virtual void fly(const Airport& destination) { // 明确指明
defaultFly(destination);
}
};
class ModelC: public Airplane {
public:
virtual void fly(const Airport& destination) { // 明确实现
...
}
};
但是这种做法可能因为过度雷同(defaultFly
和fly
)的函数名称而引起 class 命名空间的污染。所以有了第二种方法,利用“pure virtual 函数必须在 derived classes 中重新声明,但它们也可以拥有自己的实现“:
class Airplane {
public:
virtual void fly(const Airport& destination) = 0;
};
void Airplane::fly(const Airport& destination) { ... } // pure virtual 函数的实现,即缺省实现;
class ModelA: public Airplane {
public:
virtual void fly(const Airport& destination) {
Airplane::fly(destination); // 明确指明;
}
};
Last updated
Was this helpful?