C/C++ 结构与类

Posted

技术标签:

【中文标题】C/C++ 结构与类【英文标题】:C/C++ Struct vs Class 【发布时间】:2011-02-14 13:39:45 【问题描述】:

完成我的 C++ 课程后,在我看来,结构/类几乎相同,除了一些细微差别。

我以前从未用 C 编程过;但我知道它有结构。在 C 中是否可以继承其他结构并设置 public/private 修饰符?

如果您可以在常规 C 中做到这一点,为什么我们还需要 C++?类与结构有何不同?

【问题讨论】:

可能重复***.com/questions/54585/… When should you use a class vs a struct in C++?的可能重复 【参考方案1】:

不能在 C 中定义成员函数或相互派生结构。

此外,C++ 不仅仅是 C+“派生结构”。 C 中不存在模板、引用、用户定义的命名空间和运算符重载。

【讨论】:

我知道模板等在 C 中不存在,但我不知道 C 中结构的 power。所以 C++ 只使用结构来“向后”兼容 C ? 只是为了向后兼容?在实际的基础上,这可能是有原因的,但区别可能是一个意图信号:我使用 struct 的地方是指一种很大程度上被动的 POD 类型的东西。 @dmckee:不管怎样,大多数 STL 仿函数(即std::less)被定义为结构,而不是类。 C++ 与 C 不完全兼容。您可以说 struct 关键字是 C 开发人员的一种适应。我喜欢仅以有序方式保存数据但本身不提供(很多)逻辑的类的 struct 关键字。 @ypnos:见我最后的评论。两者的唯一区别是一个成员默认为public,另一个成员默认为private。【参考方案2】:

在 C++ 中,结构和类几乎相同;唯一的区别是类中的访问修饰符(用于成员变量、方法和基类)默认为私有,结构中的访问修饰符默认为公共。

然而,在 C 中,结构只是(公共)数据的聚合集合,并没有其他类似类的特性:没有方法、没有构造函数、没有基类等。虽然C++继承了关键字,它扩展了语义。 (然而,这就是为什么在结构中默认为 public 的原因——一个写得像 C 结构的结构表现得像一个结构。)

虽然可以在 C 中伪造一些 OOP——例如,定义所有将指向结构的指针作为其第一个参数的函数,或者偶尔强制具有相同的前几个字段的结构“子/超类”——它总是有点固定,并不是真正的语言的一部分。

【讨论】:

来自面向 OOP 的 .Net 人员已经定义了它this way ✓ 如果类型的实例很小且通常短暂存在或通常嵌入在其他对象中,请考虑定义结构而不是类。 X 避免定义结构,除非该类型具有以下所有特征: 1. 它在逻辑上表示单个值,类似于原始类型(int、double 等)。 2. 实例大小小于 16 字节。 3. 它是不可变的。 @Abhijeet 这就是 C# 中结构和类之间的区别,但这与 C++ 无关,对 C 更是如此。在 C# 中,类和结构实际上是不同的。在 C++ 中不是这样,C 只有没有 OO 的结构。 在 C++ 结构中保持相同的 C 语义不是更好吗?当需要使用“以 c++ 方式的结构”时,只需使用一个类?与 C 相比,我从未在 C++ 中获得“增强”结构的好处。我喜欢仍然使用 C 中设计的结构,否则使用类,允许一些例外。 @Raffaello C++ 结构具有 C 结构的所有行为。 @Caleth 并不是因为我可以在 C++ 结构中拥有私有成员,例如,我还认为 C99 结构具有与 C++ 任何版本不同的边缘情况,例如初始化。除了那个 C++ 结构调用一个默认的构造函数,这在 C 中不是这样的。对吧?【参考方案3】:

C++ 使用结构主要是为了 1) 向后兼容 C 和 2) POD 类型。 C 结构没有方法、继承或可见性。

【讨论】:

不管怎样,大多数 STL 仿函数(即std::less)被定义为结构,而不是类。 请注意,C++ 结构确实具有方法、继承和可见性。 c struct 可以包含函数指针,虽然是 type(*addr)(params);【参考方案4】:

其他就是默认访问(public/private)的区别,没有区别。

但是,一些用 C 和 C++ 编写代码的商店会使用“class/struct”来指示哪些可以在 C 和 C++(结构)中使用,哪些是仅 C++(类)。换句话说,在这种风格中,所有结构都必须使用 C 和 C++。这就是为什么很久以前就存在差异的原因,当时 C++ 仍被称为“C with Classes”。

请注意,C 联合与 C++ 一起工作,但反之则不行。例如

union WorksWithCppOnly
    WorksWithCppOnly():a(0)
    friend class FloatAccessor;
    int a;
private:
    float b;
;

同样

typedef union friend
    int a;
    float b;
 class;

仅适用于 C

【讨论】:

在你的c代码中使用cpp关键字然后声称它不兼容cpp是相当愚蠢的【参考方案5】:

C++ 的另一个区别是,当您从 struct 继承一个没有任何访问说明符的类时,它变成了公共继承,而在类的情况下它是私有继承。

【讨论】:

【参考方案6】:

我将补充现有的答案,因为 现代 C++ 现在已经成为一种东西,并且已经创建了官方 Core Guidelines 来帮助解决诸如此类的问题。

以下是指南中的相关部分:

C.2:如果类具有不变量,则使用类;如果数据成员可以独立变化,则使用 struct

不变量是对象成员的逻辑条件,构造函数必须为公共成员函数假设它建立。在建立不变量后(通常由构造函数),可以为对象调用每个成员函数。可以非正式地(例如,在评论中)或更正式地使用 Expects 来表述不变量。

如果所有数据成员都可以相互独立变化,则不可能存在不变量。

如果一个类有任何私有数据,用户不能在不使用构造函数的情况下完全初始化一个对象。因此,类定义器将提供一个构造函数并且必须指定它的含义。这实际上意味着定义者需要定义一个不变量。

执法

查找所有数据为私有的结构和具有公共成员的类。

给出的代码示例:

struct Pair   // the members can vary independently
    string name;
    int volume;
;

// but

class Date 
public:
    // validate that yy, mm, dd is a valid date and initialize
    Date(int yy, Month mm, char dd);
    // ...
private:
    int y;
    Month m;
    char d;    // day
;

Classes 适用于例如相互派生或相互关联的成员。它们还可以帮助在实例化时进行健全性检查。 Structs 非常适合拥有“数据包”,其中实际上并没有什么特别的事情发生,但从逻辑上讲,将成员分组在一起是有意义的。

由此可见,classes 的存在是为了支持封装和其他相关的编码概念,而 structs 根本没有多大用处。

【讨论】:

另一个考虑因素是便携性。 structs 是最便携的。它们可以被 C 或 C++ 或来回使用。例如,它们也可以使用 struct 模块在 Python 中解压缩。如果您的项目优先考虑与其他语言、界面或系统的兼容,请首选struct 而不是class。对于严格的程序内部事务,首选class

以上是关于C/C++ 结构与类的主要内容,如果未能解决你的问题,请参考以下文章

Java第三周总结报告

结构体与类

Swift 结构体与类

swift语言中的结构与类

➽08结构体与类

➽08结构体与类