根据我读到的,当你有一个包含数据的抽象基类时使用虚基类,所以不会复制类,但是,如果不使用虚拟类,复制类有什么问题? ?
应该避免使用保存数据的抽象基类吗?
举个例子:
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 :(得分:5)
为了简短起见,如果你不为Storable
使用虚拟继承,那么Radio
将继承两次,一次来自Transmitter
,一次来自Receiver
。< / p>
这意味着Radio
需要2个Storable
实例的内存,这是一些内存开销,而且你很可能希望两者都有相同的数据(如果你没有实际继承它) '必须手动管理)
此外,当您从Storable
调用基类函数(或访问数据成员)时,您要调用哪一个?通过Storable
继承的Transmitter
或Storable
通过Receiver
继承的Storable
继承的那个
虚拟继承只需要拥有所有继承类共享的{{1}}基类的单个实例来处理这个问题。
关于虚拟基类的mor信息,这里有一个很好的问题:In C++, what is a virtual base class?
答案 1 :(得分:2)
虚拟基类用于虚拟继承,是一种在使用多个继承时防止出现在继承层次结构中的给定类的多个“实例”的方法,即只是为了避免DIAMOND PROBLEM
。为了避免这个钻石问题,我们要么使用虚拟基类,要么使用'::'即范围分辨率运算符,以便清楚地了解我们想要使用的类的方法或数据。
请参阅Diamond Problem