【问题标题】:Why C language isn't Object Oriented language even though it has (Structures) struct keyword which is same as Class keyword of C++?为什么 C 语言不是面向对象的语言,即使它具有与 C++ 的 Class 关键字相同的(结构)struct 关键字?
【发布时间】:2021-08-15 03:15:06
【问题描述】:

在最近的一次采访中,我被问到一个问题,即类和结构之间的区别是什么,这让我想到如果区别只是访问说明符并且我们可以在 C 中使用 struct 关键字,那么为什么不是 C 对象导向的。 谁能解决我的疑惑?这种怀疑可能很幼稚,但好奇心有它自己的方式。

【问题讨论】:

标签: c++ c class object structure


【解决方案1】:

这个问题的一个问题是,为了给出答案,我们首先需要定义“什么是面向对象的语言”。

像 C++ 这样的 OO 语言具有许多映射到该语言的特性,但这并不意味着任何语言都需要具备所有这些特性才能被视为面向对象。

需要什么?

  • 封装?
  • 继承?
  • 多态性?
  • ...等等...

对我来说,最重要的特性之一是封装。通过封装,您可以将描述对象的数据和您可以对对象执行的操作联系在一起。

例如汽车对象。它将有数据成员来描述它的颜色、齿轮类型、齿轮数量、车轮数量、当前速度等。然后它将具有(成员)功能来操作汽车。你可以加速,打破,左转等等。对操作和数据进行封装,即通过调用函数对对象进行操作时,所有描述该对象的数据对函数都是可用的。

这种封装是面向对象编程的一个关键特性。

C 不能处理封装。

我们可以用数据成员创建一个struct。我们甚至可以为操作添加(成员)函数(又名函数指针)。因此,使用正确的 C 结构对象初始化,我们可以编写 OO 风格的代码,如

mycar.getSpeed();

但是……

C 在成员之间没有自动关系。我们不能调用成员函数并自动访问该对象的数据。 C没有封装的概念。

在 C 中,当调用需要访问同一对象的数据成员的成员函数时,我们需要传递对象本身(地址)才能访问数据。喜欢:

mycar.getSpeed(&mycar);
\------------/ \^^^^^/
   oo style      but explicit passing pointer to
    call         the object violates the encapsulation principle

在面向对象的语言中,这通常称为this 指针,它是隐式可用的——您不需要传递它。但是在 C 中,你必须明确地传递它。因此,使用函数指针成员来获得 OO 风格操作的好处(通常)很小——我们也可以这样做:

getSpeed(&mycar);

缺乏封装是 C 不是面向对象的原因之一。

【讨论】:

    【解决方案2】:

    在 C++ 中,structclass 之间的主要区别在于 struct 的成员默认是公共的,而 class 的成员默认是私有的。

    C 中的struct 不同,因为它不能包含成员函数,也不支持继承。它只是一种聚合不同类型变量的方法。虽然它可以包含函数指针,但它们并不像 C++ 中的成员函数那样与给定对象固有地绑定。

    虽然 C 语言将“对象”定义为“执行环境中的数据存储区域,其内容可以表示值”(C11 3.15),但就对象而言,struct 不是对象-面向的,即一组封装的数据和对其进行操作的函数。

    【讨论】:

    • 私人/公共默认值主要是装饰性的,不是主要问题。成员函数和继承是一个主要问题。 (它们只是 C++ 中的默认值;在 C 中,没有私有选项。)
    【解决方案3】:

    在 C++ 中,classstruct 是可用于声明类的关键字。 C 缺少关键字class 的事实并没有使它不那么面向对象。它使“更少面向对象”的原因是 C 结构不能有成员方法,特别是它们没有构造函数或析构函数。

    但是,面向对象和非面向对象的语言之间并没有明确的界限。面向对象是一种范式,语言本身或多或少地支持它。例如,Python 是否不是面向对象的,因为它没有“真正的”封装?当然不是。此外,考虑到 C++ 是从带有类的 C 开始的。 C++ 中内置的许多面向对象的特性都可以在 C 中进行模拟。

    【讨论】:

    • 那么关键字class 是面向对象的语言所必需的吗?顺便说一句:C 结构可以有函数指针成员,就像 c++ 成员函数一样。
    • @4386427 - 禁止整个传递隐式 this 参数和其他细节。
    • 认真的吗?面向对象和非面向对象的语言之间没有明确的区别?
    • @StoryTeller-UnslanderMonica 是的,this 指针……缺少封装……我已经发布了这个示例,说明为什么 C 不是面向对象的。如果您感兴趣,请阅读 - 欢迎反馈。
    • @kadina 是的,认真的。我找到了this,他们列出了从“一切都是对象”到“支持一些面向对象特性”的语言。没有明确规定。我怀疑这样一个明确的定义是否有任何实际用途,因为它要么太宽要么太窄
    【解决方案4】:

    为什么 C 不是面向对象的

    简短的回答 - C 在设计时并未考虑到面向对象的编程。 C++ 是。

    C 中的 struct 与 C++ 中的 classstruct 之间的主要区别在于,您不能(轻松)将 code 与 C 中的结构相关联。您可以'不在 C 中的struct 实例上执行方法,例如

    list.sort(); 
    

    sequence.average();
    

    相反,您必须将这些 struct 实例作为参数传递给函数,例如

    sort( &list );        // have to pass a pointer since we're going to modify list
    average( sequence );
    

    C 只是没有提供使面向对象编程变得容易的工具类型 - 没有封装、没有继承、没有多态(嗯,有 _Generic,但并不完全相同)。

    可以在 C 中进行面向对象的编程,但这是大量的工作,可能没有什么好处。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-31
      • 1970-01-01
      • 1970-01-01
      • 2018-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-04
      相关资源
      最近更新 更多