首先,我必须提到我已经在stackoverflow上阅读了很多C ++虚拟问题。我知道它们是如何工作的,但是当我启动项目并尝试设计一些我从不考虑/使用虚拟或纯虚拟实现的东西时。也许是因为我缺乏知识他们是如何工作的,或者我不知道如何用它们实现一些东西。我认为这很糟糕,因为我没有使用完全面向对象的开发。
也许有人可以建议我如何习惯他们?
答案 0 :(得分:1)
查看Java或C#中的抽象基类和接口,以了解纯虚拟机何时有用的想法。
虚拟功能对OO来说非常基础。 Theree有很多书可以帮助你。我自己,我喜欢拉尔曼的Applying UML and Patterns。
答案 1 :(得分:1)
但是当我启动项目并尝试设计一些我从不考虑/使用虚拟或纯虚拟实现的东西时。
这是你可以尝试的东西:
Circle
是一种 Shape
种关系?virtual
个函数但是不要仅仅为了使用它们而强制使用层次结构。我最近一直在研究的实际代码示例:
class Codec {
public:
virtual GUID Guid() { return GUID_NULL; }
};
class JpegEncoder : public Codec {
public:
virtual GUID Guid() { return GUID_JpegEncoder; }
};
class PngDecoder : public Codec {
public:
virtual GUID Guid() { return GUID_PngDecoder; }
};
答案 2 :(得分:1)
你没有必要使用它们,但它们有其优点。
通常它们被用作两种不同类型功能之间的“接口”,这些功能在代码方面并不是很相关。
一个例子是处理文件加载。一个简单的文件处理类似乎是完美的。但是,在稍后阶段,系统会要求您将所有文件转换为单个打包文件,同时保留对单个文件的支持以进行调试。你怎么处理这里的装载?显然,事情的处理方式会有所不同,因为突然间你不能只打开一个文件。相反,您需要能够查找文件位置,然后在加载之前寻找该位置,正常情况下。
显而易见的事情是实现一个抽象基类。也许称之为BaseFile。 OpenFile函数处理将根据您使用的是PackageFile还是DiskFile类而有所不同。所以,让它成为一个纯粹的虚拟。
然后,当您派生PackageFile和DiskFile类时,您可以为打开文件提供适当的实现。
然后您可以添加诸如
之类的内容#if !defined( DISK_FILE ) && defined ( _DEBUG )
#define DISK_FILE 1
#elif !defined( DISK_FILE )
#define DISK_FILE 0
#endif
#if DISK_FILE
typedef DiskFile File;
#else
typedef PackageFile File;
#endif
现在您只需使用“File”typedef来执行所有文件处理。同样,如果您没有将DISK_FILE预先定义为0或1并且设置了debug,它将自动从磁盘加载,否则它将从Package文件加载。
当然,这样的构造仍允许您在调试中从Package文件加载,只需将DISK_FILE定义为1,它还允许您通过将DISK_FILE设置为0来在发布版本中使用磁盘访问。
答案 3 :(得分:1)
我没有大量的时间ATM,但这是一个简单的例子。
在我的工作中,我维护和应用程序与各种硬件设备对话。在这些装置中,许多电动机用于各种目的。现在,我不知道你是否对电机和驱动器做了任何开发,但它们都有点不同,即使它们声称遵循像CANOpen这样的标准。无论如何,当你切换供应商时,你需要创建一些新的代码,也许你的电机或驱动器是寿命终结等等。最重要的是,这个代码必须保持与旧设备的兼容性,我们也有各种各样的类似设备的型号。总而言之,您必须处理许多不同的电机和接口。
现在,在代码中我使用了一个名为“iMotor”的抽象类,它只包含纯虚函数。在实现代码中,仅引用了iMotor类。我为不同类型的电机创建了一个具有不同实现的dll,但它们都实现了iMotor接口。因此,我需要做的就是添加/更改电机所需要做的就是创建一个新的实现并删除该dll来代替旧的。因为使用这些电机实现的代码只处理iMotor接口所以它永远不需要改变,只有每个电机的如何的实现才能做它需要改变的事情。
答案 4 :(得分:1)
如果您想要设计模式,如“策略模式”和“命令模式”,您会发现接口和多态的一些好用途。除此之外,设计模式总是非常有用。