2011-06-07 94 views
14

除了有一個純虛函數,是否有辦法阻止抽象基類的實例化?C++:防止抽象基類的任何實例化的方法?

我可以這樣做:

class BaseFoo 
{ 
    virtual void blah() = 0; 
}; 

class Foo : public BaseFoo 
{ 
    virtual void blah() {} 
}; 

,但我想避免一個虛函數表。 (每my other question about virtual destructors爲)

微軟ATL有ATL_NO_VTABLE做到這一點(或至少我認爲這是它做什麼...)

+2

爲什麼你想避免一個虛擬表? (而且,如果你永遠不會使用這個方法是虛擬的,那麼你爲什麼還要爲基類困擾?)\ – 2011-06-08 01:26:33

回答

34

一個非常明顯的方法是申報一個受保護的構造,並申報公共的構造函數在非抽象派生類中。

這當然會將corectness的負擔轉移到派生類,但至少基類是受保護的。

+0

很好。但也許不是「真的很明顯」;-) – Johnsyweb 2011-06-07 22:56:22

+3

與我期待人們發佈的瘋狂模板黑客相比,顯然是明顯的! – Blindy 2011-06-07 23:01:35

+0

好吧,很明顯給你:-) – Johnsyweb 2011-06-07 23:02:47

-4

如果你犯了一個受保護的構造如下建議,那麼當你的派生類的構造,你會得到一個錯誤類似於「不能訪問類中聲明私有成員」,還有其他一些特定於你的課程的信息。

如果你在你的基類中有純粹的虛擬方法,那麼問題不在於它們被實例化(當然不是實例化非抽象方法),但問題發生在編譯器可以銷燬的時候不能推斷出你的派生類擁有什麼。那,或者你已經實例化沒有所有者的東西! (ruh roh rgggy)

爲您的基類聲明純虛擬析構函數,然後在外部實現它。另外,永遠不要將構造函數設爲私有的(編輯:除非保證只在內部使用,例如自動構建鏈表中的下一個節點)。最近你會有史以來想要(編輯:否則)是一個明確的構造函數(但這是另一個話題)。

編輯:我可能找到了答案,但我今天仍然無法打字。

// example.h 

class A 
{ 

    A () { } 
    virtual ~A () = 0; 
}; 

class B : public A 
{ 
    B () { } 
    ~B () { } 
}; 

// example.cpp 
#include "example.h" 

A::~A () { } 
+1

'如果你創建一個受**保護的**構造函數......出錯......「無法訪問**私有**成員....」如果構造函數是'protected'而不是'private',那麼你贏了在派生類中沒有任何錯誤,告訴你訪問一個私有成員,因爲它只是非私有的。 – Pixelchemist 2015-07-10 13:15:30

+0

這整個「答案」(更多關於其他的真實答案的評論)是錯誤的。 – Blindy 2015-09-26 02:01:31