2014-02-16 36 views
4

根据我所读到的,当你有一个抽象基类持有数据时,将使用虚拟基类,因此该类不会被复制,但是,如果不使用虚拟类,复制类时会出现什么问题?为什么我应该使用虚拟基类?

应该避免保存数据的抽象基类吗?

如下的例子:

class Storable { 
public: 
    Storable(const string& s); 
    virtual void read() = 0; 
    virtual void write() = 0; 
    virtual ~Storable(); 
protected: 
    string file_name; // store in file named s 
    Storable(const Storable&) = delete; 
    Storable& operator=(const Storable&) = delete; 
}; 

class Transmitter : public virtual Storable { 
public: 
    void write() override; 
    // ... 
}; 

class Receiver : public virtual Storable { 
public: 
    void write() override; 
// ... 
}; 

class Radio : public Transmitter, public Receiver { 
public: 
    void write() override; 
    // ... 
}; 

这个例子是从书上所采取的C + +编程语言 第4版 - Bjarne的Stroustrup的。

+0

当我写了重复类,它不是在这个意义上,我不会重复的代码。 – Alex

+2

问题是您可能希望数据对于两个实例都是相同的,这很难维护 – StoryTeller

+1

查看钻石继承,例如, [这里](http://stackoverflow.com/questions/379053/diamond-inheritance-c)。 –

回答

5

要尽量简短,如果你不会从TransmitterReceiver使用虚拟继承了Storable然后Radio将继承它两次,一次一次。

这意味着Radio需要内存的Storable这两个实例,这是一些内存开销,你最希望两个都有相同的数据反正(如果你不继承它,事实上你必须手动管理)。
此外,当您从Storable(或访问数据成员)调用基类函数时,您想调用哪一个函数?从Storable的一个打通Transmitter继承或从Storable是打通Receiver

虚继承继承了一个需要照顾,与仅具有都继承类共享Storable基类的一个实例。

有关虚基类更多资料,有一个很好的问题在这里:In C++, what is a virtual base class?

+0

那么,每次我使用抽象基类时,我应该使用虚拟继承? – Alex

+1

@Alex只有在继承两次时才会出现问题,如继承自'T2'和'T3'的'T1'和'T4'的'T2'和'T3'。 –

+1

如果你只能继承一个'T1'的实例,那么就不需要虚拟基类。 –

2

虚基类是在虚拟继承使用,是防止多个“实例”出现在继承层次给定类的一种方式当使用多个继承,即只是为了避免DIAMOND PROBLEM。为了避免这个钻石问题,我们要么使用虚拟基类,要么使用'::'即范围解析运算符来清楚地理解我们想要使用的类的方法或数据。 请参考Diamond Problem

相关问题