类继承/组合设计
design of class inheritance/compostion
我有两个类:读者和作家。对于这两个类,我都有一个抽象接口,因为数据源/目标应该是灵活的:
class abstract_reader {
...
};
class concrete_reader : public abstract_reader {
DATATYPE m_data;
...
};
class abstract_writer {
...
};
class concrete_writer : public abstract_writer {
DATATYPE m_data;
...
};
编写者应同时具有读取和写入的功能 concrete_writer的读取部分的实现与concrete_reader的实现相同。组合这些类的好方法是什么?
你想要的有点令人困惑,但有很多方法:
- 从两个抽象类派生编写器
- 按住指向编写器中具体读取器的指针
- 在编写器中保存具体读取器的实例
- 从编写器中删除读取功能,并创建可以读取和写入的第三个类。
就个人而言,我会遵循最后一种方式,然后您将拥有一整套只读、仅写作和两者兼而有
为什么作者想知道如何阅读?也许你应该考虑第三类,结合阅读和写作功能。
如果您确信没问题,只需从abstract_reader
和abstract_writer
中得出作者即可。只要它们是正确实现的接口(例如,没有字段),一切应该都可以正常工作。
哦,也许合并模板会很好(我注意到了神秘的DATATYPE
class concrete_writer : public abstract_writer, public abstract_reader {
public:
void read() { // or whatever the proper override is for abstract_reader
reader.read();
}
private:
concrete_reader reader;
};
但是,正如@Bartek指出的那样,有一个名为"writer"的类也阅读似乎很奇怪。
首先,如果它只是一个writer
,它不应该知道如何阅读。 什么当您将编写器实现到屏幕时发生? 尽管如此,仍然有一个 ReaderWriter
,除了Reader
和Writer
之外,是一个很合理的选择,这会产生同样的问题。
我这样做的方法是首先,将ReaderWriter
定义为继承自Reader
和Writer
的接口:
class Reader
{
private:
// Pure virtual functions to the implementation...
public:
virtual ~Reader() {}
// Interface...
};
class Writer
{
private:
// Pure virtual functions to the implementation...
public:
virtual ~Writer() {}
// Interface...
};
class ReaderWriter : public virtual Reader, public virtual Writer
{
// Just joins the two; adds nothing new of its own
};
请注意虚拟继承。 这通常应该是默认值,当您正在扩展接口。 一旦你有了它,你就可以(通常)使用混合实现:
class ConcreteReader : public virtual Reader
{
// Overrides for the pure virtual functions, + any data needed.
public:
ConcreteReader(); // Or with parameters, as needed.
};
class ConcreteWriter : public virtual Writer
{
// Overrides for the pure virtual functions, + any data needed.
public:
ConcreteWriter(); // Or with parameters, as needed.
};
class ConcreteReaderWriter : public ReaderWriter, public ConcreteReader, public ConcreteReaderWriter
{
};
接收Reader*
可以读取的客户端代码;客户端代码收到一个可以写入Writer*
;和接收 ReaderWriter
可以做到其中之一。 当然,如果客户有一个 Reader*
,它总是可以尝试将其dynamic_cast
到Writer*
或 ReaderWriter*
,如果dynamic_cast成功,它也可以写入。
编辑:我忘了提:这种技术被称为mixins。
- 混合组合和继承的C++问题
- C++基于策略的设计:继承与组合
- 工厂方法模式使用继承而抽象工厂模式使用组合如何
- vector_base继承与组合
- 如何在 c++ 中将多重继承与组合一起使用?
- 是否可以使用 Gtk::D rawingArea (GTKmm) 作为组合而不是继承?
- C++:树根应该使用继承而不是组合吗?
- 必要时违反组合而不是继承可以吗?
- 避免使用组合进行额外的堆分配(过度继承)
- 为什么我在使用组合而不是继承时得到 C4624(无法访问基类析构函数)
- 编译器如何在继承C++中进行组合
- 类继承/组合设计
- Qt和C++:双重继承与组合
- 使用组合而不是继承的方法转发(使用C++特性)
- 将继承更改为组合
- C++中组合关系的继承
- 为什么与组合相比,私有继承会增加有人破坏我的代码的概率
- C++ 继承和组合一起使用
- 可变模板和多重继承的组合
- 两个接口,多个继承组合成一个容器