C++ 过程式程序和面向对象的程序有什么区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/530741/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 15:49:24  来源:igfitidea点击:

What's the difference between a procedural program and an object oriented program?

c++coopprocedural-programming

提问by paxdiablo

I'm fairly new to programming but I've been reading some interesting discussions on StackOverflow about various programming approaches. I'm still not 100% clear on what the difference is between procedural programming and object oriented programming. It sounds like object oriented programming still uses procedures (methods) but everything is organized differently because the object is the star of the show. But it seems to me that procedures still allow you to do all of the same things. Like in C, you can put all of your similar procedures into a library. So couldn't you really say that a library in C is similar to an object in C++?

我对编程还很陌生,但我一直在阅读有关各种编程方法的 StackOverflow 上的一些有趣讨论。我仍然不是 100% 清楚过程编程和面向对象编程之间的区别。听起来面向对象编程仍然使用过程(方法),但一切都以不同的方式组织,因为对象是表演的明星。但在我看来,程序仍然允许您做所有相同的事情。就像在 C 中一样,您可以将所有类似的过程放入一个库中。所以你真的不能说 C 中的库类似于 C++ 中的对象吗?

采纳答案by Serx

The difference between the two is subtle but significant.

两者之间的差异是微妙但显着的。

In a procedural program, modules interact by reading and writing state that is stored in shared data structures.

在过程程序中,模块通过读取和写入存储在共享数据结构中的状态进行交互。

In an object oriented program, modules in the form of objects interact by sending messages to other objects.

在面向对象的程序中,对象形式的模块通过向其他对象发送消息来进行交互。

回答by paxdiablo

In a procedural program, the code is king and the data is subordinate. In other words, you have programs which act on data and they're not usually tightly bound.

在程序化程序中,代码为王,数据为从。换句话说,您的程序对数据起作用,并且它们通常不是紧密绑定的。

In the OO world, objects are the primary thing of interest. An object consists of data andthe code that is allowed to act on that data, and they are very tightly bound. It is the concept of encapsulation, the hiding of information.

在 OO 世界中,对象是最重要的事物。一个对象由数据允许对数据进行操作的代码组成,它们之间的联系非常紧密。它是封装的概念,信息的隐藏。

An example, let's say you have a number and you want to double it. A procedural way of doing this is:

举个例子,假设你有一个数字,你想把它翻倍。这样做的程序方法是:

n = n * 2

The code here quite explicitly multiplies n by 2 and stores the result back into n.

这里的代码非常明确地将 n 乘以 2 并将结果存储回 n。

The OO way of doing this is to send a "message" to the number object telling it to double itself:

这样做的 OO 方法是向 number 对象发送一条“消息”,告诉它自己加倍:

n.double();

The advantage of this is called polymorphism. What happens when you decide you want to be able to double a string like "bob". In the procedural world, you'd have to provide more code to do the doubling but you'd also have to call that code differently.

这样做的优点称为多态性。当您决定将像“bob”这样的字符串加倍时会发生什么。在程序世界中,您必须提供更多代码来进行加倍,但您还必须以不同方式调用该代码。

With OO, you create a string object which can also take the 'double' message. The code to double a string belongs to the string object so it knows it has to act differently to the number object. If it decided that "bob" * 2 was "bobbob", the code would look something like:

使用 OO,您可以创建一个字符串对象,该对象也可以接收“double”消息。将字符串加倍的代码属于字符串对象,因此它知道它的行为必须与数字对象不同。如果它决定“bob” * 2 是“bobbob”,代码将类似于:

class number:                    class string:
    int n                           char array s
    procedure double:               procedure double:
        n = n * 2                       s = string_join(s,s)

Then you could call x.double() no matter what actual type x was (number or string) and it would know which code to run - this greatly simplifies your code. You can double integer, strings, matrices, complex numbers, reals, window sizes on your monitor and all sorts of different things.

然后你可以调用 x.double() 不管 x 是什么实际类型(数字或字符串),它会知道要运行哪个代码 - 这大大简化了你的代码。您可以将整数、字符串、矩阵、复数、实数、显示器上的窗口大小以及各种不同的东西加倍。

And you're right, a C library can be made to look a little bit like objects. The classic example is stdio.h- you don't ever care whata FILE*actually points to, just the fact that it will behave in a certain way. The FILE*, fopen(), fclose()and other functions are an class of sorts representing the I/O capabilities of C.

你是对的,可以使 C 库看起来有点像对象。经典的例子是stdio.h——你永远不关心a实际指向什么FILE*,只关心它会以某种方式表现的事实。的FILE*fopen()fclose()和其他功能是代表C的I / O能力的类各种

回答by Aram Verstegen

You can program procedurally in most OO languages, but the power of OO comes from the ability to inherit, encapsulate and abstract that procedural logic. I think you are correct, a library should look a lot like a class. It should have its own scope and encapsulate logic behind functions with meaningful names.

您可以使用大多数面向对象语言进行程序化编程,但面向对象的强大功能来自于继承、封装和抽象该过程逻辑的能力。我认为你是对的,图书馆应该看起来很像一个班级。它应该有自己的作用域,并用有意义的名称封装函数背后的逻辑。

回答by Uri

You are correct in your observation that object-oriented programs are based in many ways on the procedural paradigm. You are also correct in that syntactically all that really happens is that you invoke functions. In fact, you could implement many features of object oriented languages using procedural mechanisms (e.g., function pointers in C++). You could thus do an object-oriented design and still implement it in a procedural language (e.g., like old C++ compilers did).

您的观察是正确的,即面向对象的程序在许多方面都基于过程范式。您在语法上也是正确的,真正发生的就是您调用函数。事实上,您可以使用过程机制(例如,C++ 中的函数指针)实现面向对象语言的许多特性。因此,您可以进行面向对象的设计,并且仍然以过程语言(例如,像旧的 C++ 编译器所做的那样)来实现它。

The importance of the object oriented paradigm is not as much in the language mechanism as it is in the thinking and design process. In procedural programming the thinking is about operations and breaking those operations down using other operations, grouping them into modules, etc. This means that the data or state falls into a secondary importance. It is like thinking of mathematical operations.

面向对象范式的重要性不在于语言机制,而在于思维和设计过程。在过程编程中,思考是关于操作并使用其他操作将这些操作分解,将它们分组为模块等。这意味着数据或状态处于次要地位。这就像思考数学运算。

The object oriented paradigm, on the other hand, says that you need to think of state and operations together as an entity, and then design your program as interactions between entities that exchange state and activate operations.

另一方面,面向对象范式表示您需要将状态和操作一起视为一个实体,然后将您的程序设计为交换状态和激活操作的实体之间的交互。

回答by dsimcha

IMHO, object oriented programming is a concept that exists at a higher level of abstraction than procedural programming. The two are not mutually exclusive in that individual methods in an OO program look pretty much the same as individual functions in a procedural program. This contrasts with, for example, functional programming, which requires a completely different mindset. Furthermore, you can write procedurally in an OO language by making everything static, etc. You can be a human compiler and write effectively OO code in C by using lots of function pointers and struct pointer casting.

恕我直言,面向对象编程是一个存在于比过程编程更高抽象级别的概念。这两者并不相互排斥,因为 OO 程序中的各个方法看起来与过程程序中的各个函数几乎相同。例如,这与函数式编程形成对比,后者需要完全不同的思维方式。此外,您可以通过将所有内容设置为静态等方式以面向对象语言编写程序。您可以成为人类编译器,并通过使用大量函数指针和结构指针转换来有效地用 C 编写面向对象代码。

OO, then, is more of a design philosophy and world view than something w/ a rigorous definition. It requires that inheritance, polymorphism, etc. be used as major patterns in structuring your code, and that syntax be provided to make these expressible without resorting to low-level tricks. It requires that you think of code that acts on the state of a collection of data as being a property of the data, not a procedure that exists by itself. It is not black and white. Your code can be "more" or "less" OO depending on how heavily you rely on inheritance, polymorphism, classes and the "methods as a property of data" worldview as a means of structuring and explaining/understanding your code.

那么,OO 更像是一种设计哲学和世界观,而不是具有严格定义的东西。它要求将继承、多态等用作构建代码的主要模式,并提供语法以使其可表达,而无需求助于低级技巧。它要求您将处理数据集合状态的代码视为数据的属性,而不是本身存在的过程。它不是非黑即白。您的代码可以是“更多”或“更少”的面向对象,这取决于您对继承、多态性、类的依赖程度以及“方法作为数据的属性”世界观作为构建和解释/理解代码的一种手段。

回答by hasen

OO is mostly a mind set. You can program OO in C (if you really want to ... ), and you can perfectly have procedural code in C++/Java; what I mean is, even if you use classes on the surface, it could still be procedural.

OO 主要是一种心态。你可以用 C 来编程 OO(如果你真的想……),你可以完美地用 C++/Java 编写程序代码;我的意思是,即使你在表面上使用类,它仍然可能是程序性的。

The idea behind OO is abstraction of state. Instead of "thinking" in terms of "groupings of data", you "think" in terms of "objects", where an object is an "interface" for "grouping of data and ways to manipulate this data".

OO 背后的思想是状态的抽象。您不是根据“数据分组”进行“思考”,而是根据“对象”进行“思考”,其中对象是“数据分组和操作该数据的方法”的“接口”。

It all sounds philosophical, because it is.

这一切听起来很哲学,因为它是

There's a lot to say here, and it can't be all said in a small SO post, so I'll leave it here.

这里有很多话要说,不能在一个小的SO帖子中全部说出来,所以我就留在这里。

UPDATE
As mentioned in Flanagan's answer, OO languages implement constructs that utilize this abstraction.

更新
Flanagan 的回答中所述,OO 语言实现了利用此抽象的构造。

I mean, you could technically "hack" classes and polymorphism in terms of structs, functions, and function pointers.

我的意思是,您可以在结构、函数和函数指针方面从技术上“破解”类和多态性。

Here's an example of OO in C

这是C 语言中OO示例

回答by vanja.

The difference is that objects have procedures and related data in the same place - procedural languages use 'structs' (things that hold related data together) which keeps the data separate from the procedures. Effectively, anything you do in an OO language should be possible in a procedural language with a combination of structs and procedures.

不同之处在于对象在同一位置具有过程和相关数据 - 过程语言使用“结构”(将相关数据保存在一起的东西),它将数据与过程分开。实际上,您在 OO 语言中所做的任何事情都应该可以在具有结构和过程组合的过程语言中实现。

The main difference is the mind set that an OO languages puts programmers in.

主要区别在于面向对象语言让程序员进入的思维模式。

回答by Steven A. Lowe

[pardon the primer style, it's late and i'm tired]

[原谅初级风格,来晚了,我累了]

procedures process data - data in, apply some processing, get data out

程序处理数据 - 输入数据,应用一些处理,取出数据

sometimes, some of the data elements are related to some of the other data elements, and it's convenient to group them together into a data structure, which can then be manipulated and addressed as a single unit.

有时,一些数据元素与其他一些数据元素相关,将它们组合成一个数据结构很方便,然后可以将其作为一个单元进行操作和寻址。

now our procedure can take a data structure as input and alter it and/or produce another data structure as output

现在我们的程序可以将一个数据结构作为输入并改变它和/或产生另一个数据结构作为输出

occasionally we notice that some procedures are only concerned with a certain kind of data structure; it is convenient to group these procedures together with their data structure, and call it an object.

偶尔我们会注意到有些程序只关心某种数据结构;将这些过程与其数据结构组合在一起,并将其称为对象是很方便的。

a template for creating objects is called a class; an object is said to be an instanceof a class

用于创建对象的模板称为;一个对象被称为一个类的实例

we may notice that one class is very much like another, so instead of copying and pasting code we let one class inheritfrom another: the subclassinherits from the superclassor "base class". In this way the subclass has access to all of the data structures and procedures of the superclass, and can augment or override them in certain ways

我们可能会注意到一个类与另一个类非常相似,因此我们不是复制和粘贴代码,而是让一个类继承另一个子类继承自超类或“基类”。通过这种方式,子类可以访问超类的所有数据结构和过程,并且可以以某些方式增加或覆盖它们

if we politely request an object to do something for us instead of brutally calling its procedures directly, this is called message passing, even if no actual 'message' is transmitted. The joy here is that many different kinds of objects may understand the same message, which leads to the notion of polymorphism. For example, we can ask many different kinds of documents to Print themselves, and they each respond appropriately.

如果我们礼貌地请求一个对象为我们做某事而不是粗暴地直接调用它的过程,这称为消息传递,即使没有实际的“消息”被传输。令人高兴的是,许多不同种类的对象可能会理解相同的消息,这导致了多态的概念。例如,我们可以要求多种不同类型的文档自行打印,它们各自做出适当的响应。

a language that supports objects (via classes or not) with message passing and inheritance is called object-oriented. If there is no inheritance, the language is merely object-based.

一种通过消息传递和继承支持对象(通过或不通过类)的语言称为面向对象。如果没有继承,语言只是基于对象的

good luck with your studies!

祝你学业顺利!

回答by dmckee --- ex-moderator kitten

Procedural is part of the procedural/functional/logical (or logic oriented) distinction (compare c, lisp, and prolog) between different ways of describing what a program should do.

过程是描述程序应该做什么的不同方式之间的过程/功能/逻辑(或面向逻辑)区别(比较 c、lisp 和 prolog)的一部分。

Object orientation is orthogonal to this other idea, and describes a means of grouping sub-programs with data. C++ and java are procedural languages with object oriented features; fortran77 is a procedural languages without object oriented features. Common lisp supports object orientation; some older lisps do not. Plain vanilla prolog does not support objects, and I can't name a logic oriented language that does (I don't do logic oriented programming, it is on my list of things to do when I havesome copious spare time. I barely do functional programming).

面向对象与另一个想法是正交的,它描述了一种将子程序与数据分组的方法。C++ 和 java 是具有面向对象特性的过程语言;fortran77 是一种没有面向对象功能的过程语言。Common lisp 支持面向对象;一些较旧的 lisp 没有。普通的 prolog 不支持对象,我无法命名一种支持逻辑的语言(我不做面向逻辑的编程,当我大量空闲时间时,它在我要做的事情清单上。我几乎不这样做函数式编程)。

As others have noted, however, proper object oriented thinking changes how you do your programming as much as a switch from procedural to functional.

然而,正如其他人所指出的那样,正确的面向对象思维改变了您进行编程的方式,就像从程序到功能的转换一样。



BTW-- I see "procedural" used a lot to distinguish non-object-oriented procedural languages from their object-oriented brethren, but I think this is a poor usage driven by the lack of a clean adjective for "not object oriented". YMMV.

顺便说一句——我看到“过程化”经常用于将非面向对象的过程化语言与其面向对象的兄弟区分开来,但我认为这是一个糟糕的用法,因为“非面向对象”缺乏一个干净的形容词。天啊。

回答by Maurice Flanagan

Its easier to understand in context, look at other abstractions introduced between languages.

在上下文中更容易理解,请查看语言之间引入的其他抽象。

A key difference between assembly language and a procedural language like C or Pascal is the introduction of the "procedure" abstraction. People writing assembly code create procedures, but its hard and error prone, a procedural language gives you tools to make it easier.

汇编语言与 C 或 Pascal 等过程语言之间的主要区别在于引入了“过程”抽象。编写汇编代码的人会创建过程,但它很难且容易出错,过程语言为您提供了使其更容易的工具。

The difference between a procedural language and an OO language like C++ is the "object" abstraction. People who write "c" often create conceptual objects but its difficult and error prone, an OO language gives you tools to make it easier.

过程语言和像 C++ 这样的面向对象语言之间的区别在于“对象”抽象。编写“c”的人通常会创建概念对象,它既困难又容易出错,OO 语言为您提供了使其更容易的工具。

Things like Sing#from Microsoft (or Erlang) add the Message/Process abstraction into the language. Sure, you can do message passing and process creation in assembly, C or C++ but Sing# makes it easier.

来自 Microsoft(或 Erlang)的Sing#之类的东西将 Message/Process 抽象添加到语言中。当然,您可以在程序集、C 或 C++ 中进行消息传递和进程创建,但 Sing# 使它更容易。

It all comes down to the same machine code, these abstractions are purely for the benfit of our brains, not the computer.

这一切都归结为相同的机器代码,这些抽象纯粹是为了我们的大脑而不是计算机。