![](/img/trans.png)
[英]Is it safe to privately inherit from a class with a non-virtual destructor?
[英]does it make sense to inherit privately from an abstract (pure virtual) class?
假設這個構造
struct InterfaceForFoo
{
virtual void GetItDone() = 0;
};
class APoliticallyCorrectImplementationOfFooRelatedThings : private InterfaceForFoo
{
public:
void GetItDone() { /*do the thing already*/ };
};
現在,我想知道以這種方式從接口私有繼承是否有任何有用的場景。
呵呵,這里的每個人都說“不”。 我說“是的,這確實有道理”。
class VirtualBase {
public:
virtual void vmethod() = 0;
// If "global" is an instance of Concrete, then you can still access
// VirtualBase's public members, even though they're private members for Concrete
static VirtualBase *global;
};
// This can also access all of VirtualBase's public members,
// even if an instance of Concrete is passed in,
void someComplicatedFunction(VirtualBase &obj, ...);
class Concrete : private VirtualBase {
private:
virtual void vmethod();
public:
void cmethod() {
// This assignment can only be done by Concrete or friends of Concrete
VirtualBase::global = this;
// This can also only be done by Concrete and friends
someComplicatedFunction(*this);
}
};
將 inheritance 設為private
並不意味着您無法從 class 外部訪問VirtualBase
的成員,它僅意味着您無法通過對Concrete
的引用訪問這些成員。 但是, Concrete
及其朋友可以將Concrete
的實例強制轉換為VirtualBase
,然后任何人都可以訪問公共成員。 簡單地,
Concrete *obj = new Concrete;
obj->vmethod(); // error, vmethod is private
VirtualBase *obj = VirtualBase::global;
obj->vmethod(); // OK, even if "obj" is really an instance of Concrete
在面向 object 的方面,沒有用於抽象class
的private
inheritance 的用例。
但是,如果您想強制您的孩子class
必須派生某些方法,那么您可以使用它。 例如:
struct implement_size
{
virtual size_t size () = 0;
};
class MyVector : private implement_size
{
public:
size_t size () { ... } // mandatory to implement size()
}
class MyString : private implement_size
{
public:
size_t size () { ... } // mandatory to implement size()
};
因此,它只是有助於維護個人編碼紀律。 這個例子的信息是,inheritance 不僅僅意味着面向 object 的目的。 您甚至可以使用 inheritance 來停止 inheritance 鏈(類似於 Java final)。
問題是為什么基礎 class 只有純虛方法很重要?
這兩件事幾乎沒有關系。 私有意味着它是 class 的實現細節,而不是公共接口的一部分,但您可能希望將接口實現為實現細節。 假設您編寫了 class,並且您決定通過需要您實現接口的庫來實現該功能。 那是一個實現細節,沒有必要僅僅因為接口只有純虛函數就公開inheritance。
誒? 不,這絕對沒有意義,因為您提供接口的原因是您希望其他人通過該接口使用您的 class 。 如果他們不知道您實施它,那將如何工作?
#include <vector>
class Fooable{
public:
virtual void foo() = 0;
};
class DoesFoo
: private Fooable
{
void foo();
};
int main(){
std::vector<Fooable*> vf;
vf.push_back(new DoesFoo()); // nope, doesn't work
vf[0]->foo();
}
上面的示例不起作用,因為外界不知道DoesFoo
是Fooable
,因此您不能new
它的實例並將其分配給Fooable*
。
並不真地。 如果你需要一個 function,你實現它。 強制使用其他類無法使用的 function 是沒有意義的。
我不知道為什么要從接口私下繼承; 這違背了接口的目的。
如果它不是一個接口,而是一個 class,這是有道理的:
class A {
virtual void foo() = 0;
void bar() {
foo();
}
};
class B : private A {
virtual void foo() {
}
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.