2012-12-15 23 views
2

將純虛擬接口的實現放入cpp並完全跳過頭文件是一種好的做法嗎?cpp文件中的純虛擬接口實現

A.h 
struct A 
{ 
    virtual void func() = 0; 
}; 
B.cpp 
class B : public A 
{ 
    virtual void func() override { 
    ... 
    } 
} 
+2

如果'B'本身不需要在翻譯單元之外訪問,那麼我不明白爲什麼不能。 – NPE

回答

1

必須有人使用B,他們必須從某個地方,甚至如果他們通過A*永遠只能解決他們得到的B實例。所以,你可以有例如:

struct A 
{ 
    virtual void func() = 0; 
    virtual ~A() {} 
}; 

了Bh

#include "A.h" 
A *Bfactory(); 

B.cpp

#include "B.h" 
struct B : public A { ... }; 
A *Bfactory() { return new B(); } 

在另一方面,這是一個相當 「雞肋」 功能工廠因爲它只能返回B的實例。也許在某處會有另一個工廠函數,根據其參數創建不同派生類A。該功能需要包括A.h,B.h,C.h等,但是如果它總是使用Bfactory來創建B的實例,那麼它不需要類別定義B。所以在這種情況下,類定義只存在於B.cpp中。

順便說一句,我已經從工廠返回了一個原始指針。在現實生活中,您可能更願意返回unique_ptr或其他智能指針。如果你這樣做,那麼實際上可以避免在A中需要虛擬析構函數。但我懷疑這往往是值得的。

+1

,但你不能但在結構A裏面有一個靜態函數,例如static A * create_b(); static A * create_c(); 然後在B.cpp中你做A * A :: create_b(){return new B; } – hidayat

+1

@hidayat:你可以。我通常不會設計應該「知道」所有派生類的基類,但它是有效的。同樣,在我的代碼中,您可以將免費函數'Bfactory'的聲明從'B.h'移動到'A.h'。如果你在'A.h'中聲明一個函數並在'B.cpp'中定義它(特別是它是類'A'的成員函數),那麼你會憤怒和沮喪。但他們會生存。 –