C中实现"面向对象的常见做法"正在使用函数指针数组。这似乎与C ++ vtable类似,实质上C ++虚函数机制只是函数指针数组的语法糖。
但是C机制还有一个在C ++中缺少的附加功能。函数指针可以为NULL,调用者可以检查函数是否为NULL,以查看对象是否实现某种方法。但是在C ++中,方法不能为NULL,并且类不能实现"一种方法。
在C ++中模仿这种行为的最接近的方法是什么?
答案 0 :(得分:8)
这种做法有时被称为fat interface,被视为反模式。
正确的面向对象的方法是提供几个子类的层次结构,即将“可选”方法分离为一个额外的接口,只让一些类实现该接口。
你测试一个类是否通过测试它是否是相关接口的实例来实现这些方法。
(顺便提一下,在C中也是如此 - 虽然我从未在严肃的项目中使用过C,但我怀疑你应该在那里使用NULL
函数指针,而不是建模正确的类型层次结构。)
答案 1 :(得分:2)
我认为这不是C ++的有效用法。在C ++中,你应该编程到一个接口。方法存在与否。您似乎将C ++视为简单的C与类。还有一点。
接口说有一个方法,或者说它没有。这提供了C不会的编译时安全性。
答案 2 :(得分:1)
有一个基本虚函数,它会在基类中引发异常(让我们称之为not_implemented
)。
无论如何,你通常不会那样做。你最好有一个适当的类层次结构,如其他评论中所述。
答案 3 :(得分:1)
最接近的方法是设计一个类层次结构,以准确地模拟C风格的vtable实现的内容。
具有不同数量元素的两个函数指针数组(vtable)正在为两个单独的类建模。这很明显,但是很明显,即使数组的大小相同,具有不同数量的非null 元素的vtable也会对单独的类进行建模。
例如,假设我们有一个vtable和两个聚合它的对象:
VTABLE OBJECT A OBJECT B
STRUCTURE
+-------------+ +-------------+ +-------------+
| pfnCreate | | 0x..... | | 0x..... |
+-------------+ +-------------+ +-------------+
| pfnUpdate | | 0x..... | | NULL |
+-------------+ +-------------+ +-------------+
| pfnDelete | | 0x..... | | 0x..... |
+-------------+ +-------------+ +-------------+
这两个对象不属于同一个类(至少使用类的C ++定义),因此不能仅使用一个类来模拟事务状态就不足为奇了。转换为C ++,这看起来像
class Something {
public:
void Create();
void Delete();
};
class UpdatableSomething : public Something {
public:
void Update();
}
其中B是Something
,A是UpdatableSomething
。
答案 4 :(得分:0)
听起来您正在尝试在运行时进行兼容性检查。有几种方法可以构建类层次结构,您可以使用胖接口,其中基类实现所有可能的派生函数,并在派生类不覆盖实现时让它们在执行时抛出错误。这就是你在C中所做的一切。
另一种更理想的方法是通过功能类和使用多重继承来混合功能。
请参阅第9-11页以获取有关设计和实现此内容的更多详细信息。
http://www.umich.edu/~eecs381/lecture/IdiomsDesPattsStructural.pdf