Oop 非面向对象编程中多态性的替代方案?
假设我们有一个包含不同元素的绘图程序,如圆、矩形、三角形等。不同类型的对象都需要类似的函数,例如Oop 非面向对象编程中多态性的替代方案?,oop,polymorphism,procedural-programming,Oop,Polymorphism,Procedural Programming,假设我们有一个包含不同元素的绘图程序,如圆、矩形、三角形等。不同类型的对象都需要类似的函数,例如draw()来显示它们自己 我想知道程序员如何处理目前通常由多态性解决的问题,即遍历一组不相同的元素并跨不同对象调用公共功能 想到的一种方法是,让一个结构具有指向适当函数(或函数指针数组中的索引)的函数指针,以及指向实际实例的空指针,并传递转换为函数中适当类型的指针。但这正是我——一个在这个问题上毫无头绪的人——所做的 我确实意识到这可能是一个不切实际的问题,但由于我在“过去”的日子里没有出现过,我真
draw()
来显示它们自己
我想知道程序员如何处理目前通常由多态性解决的问题,即遍历一组不相同的元素并跨不同对象调用公共功能
想到的一种方法是,让一个结构具有指向适当函数(或函数指针数组中的索引)的函数指针,以及指向实际实例的空指针,并传递转换为函数中适当类型的指针。但这正是我——一个在这个问题上毫无头绪的人——所做的
我确实意识到这可能是一个不切实际的问题,但由于我在“过去”的日子里没有出现过,我真的很想知道这个问题是如何解决的。在程序设计中使用了什么样的方法,它有一个性能上的好处,因为我们都知道多态性在像C++这样的快速语言中也有开销,因为虚拟方法查找。在程序语言中,例如,例如,通过定义<代码>()的单独实现来解决。用于每个自定义数据类型(可能表示为结构)的函数。任何公共功能都将分解为单独的功能,该功能在每个结构的共享元素上运行(例如对象中心的x和y坐标,将出现在每个结构中)。从代码和功能的角度来看,这与利用多态性的OOP布局没有太大区别,在这种布局中,您仍然必须在基类中实现一个共享的
draw()
方法,并在特定的子类中重写它。对于过程语言,我们不会将这些函数定义拆分为单独的“对象”
有一些奇特的方法可以从过程语言中获得类似对象的行为,例如联合类型或带有额外布尔值的单一单片类型,以确定是否正在使用特定元素。这将允许您编写单个draw()
函数,该函数可以根据启用的元素执行逻辑切换。实际上,我在基于CORBA的系统中看到的唯一地方是,用C编写的程序必须模仿通过IDL传播的OOP语言的一些行为(即,将Java对象转换为可以解码为C风格结构的结构)
<>对于在C++和java语言中的虚拟方法查找开销,这是一种不能完全避免的面向对象语言。正确使用
final
关键字(允许编译器/JVM优化方法查找表)可以很好地缓解这种情况。这不是对示例的直接回答,而是对您的注释的地址,它显示了错误的观点
我只是想知道那个特别的问题,我很感兴趣
是否有更有效的方法来避免性能开销
虚拟方法的应用
这里有一些东西需要理解。每件事都有权衡。设计模式和OO具有我们所喜爱的所有已知优点,但也有缺点,例如类太多、内存开销、由于许多方法调用而导致的性能开销等
另一方面,旧的“程序性”方式在客观方面也有一些优势;编写代码“简单”(无需考虑如何设计系统,只需将所有内容放在主目录中),并且在许多方面的开销较少(更少的内存开销,因为需要更少的类和更紧凑的对象-不需要虚拟表等-和更少的方法调用,所以可能更好的性能,动态绑定没有性能开销-不管现在的开销是什么…-)
但这不是特定问题实例的权衡,而是经验表明构建软件的正确方法。重用模块化的代码,并协助单独测试(质量保证),可读性,可维护性,可扩展性是软件开发的主要驱动力,这些属性已被充分理解
因此,在某些情况下,一个真正优秀的C/C++程序员可以按照您所说的“旧方法”进行编程,但是,它为这个特定程序带来的性能好处是否值得这样一个事实,即以后没有人能够维护或维持它
再举一个类似的例子:你可以用同样的方式提问吗?为什么在web开发中使用多层架构?只需将所有内容都放在一台服务器上,速度就会快得多,因为在查询后端和所有层的UI数据时不会有延迟,在查询远程数据库时也不会有网络延迟。
当然,你说得有道理。但是,你可以问问自己,这能随着负载的增加而扩展吗?答案是否定的。那么,可伸缩性对你来说很重要吗?还是你想保持“将所有东西都放在一台服务器上”的原则想法?如果你的收入来自电子站点,那么你不能为更多的客户提供服务这一事实不会让你的客户感到高兴,因为你为前100个客户提供的服务真的很快……无论如何,这是我的观点一个非常简单的例子 如果您对此感兴趣,您可以在Linux内核中找到更多
#include <stdio.h>
struct shape {
void (*say_hello)(void);
};
void circle_say_hello(void)
{
printf("Hi I am circle!\n");
}
void square_say_hello(void)
{
printf("Meh I am square.\n");
}
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
int main(int argc, char *argv[])
{
struct shape circle = { .say_hello = circle_say_hello, };
struct shape square = { .say_hello = square_say_hello, };
struct shape* shapes[] = {&circle, &square};
int i;
for (i = 0; i < ARRAY_SIZE(shapes); i++) {
if (shapes[i] && shapes[i]->say_hello)
shapes[i]->say_hello();
}
return 0;
}
#包括
结构形状{
void(*打招呼)(void);
};
虚空圆圈\说\你好(虚空)