在哪种情况下,在C ++中使用struct比使用class更好?


#1楼

它们是相同的东西,具有不同的默认值(对于class默认为private,对于struct默认为public),因此从理论上讲它们是完全可以互换的。

因此,即使我只想打包一些信息来移动,我也使用了一个结构,即使我在其中放了一些方法(但不是很多)。 如果是最不透明的东西,主要用途是通过方法,而不是直接传递给数据成员,则使用完整类。


#2楼

默认情况下,结构具有公共访问权限,而类则默认具有私有访问权限。

我个人将结构用于数据传输对象或用作值对象。 当这样使用时,我将所有成员声明为const,以防止被其他代码修改。


#3楼

正如其他所有人所指出的,实际上只有两种实际语言差异:

  • struct默认为公共访问,而class默认为私有访问。
  • 继承时, struct默认为public继承,而class默认为private继承。 (具有讽刺意味的是,与C ++中的许多事情一样,默认值是向后的:到目前为止, public继承是更常见的选择,但是人们很少声明struct只是为了节省键入“ public ”关键字的时间。

但是实际上,真正的区别是在声明了构造函数/析构函数的class / struct与未声明构造函数/析构函数的class / struct之间。 对于“普通数据” POD类型有某些保证,一旦您接管了班级的建设,这些保证将不再适用。 为了清楚地区分,许多人故意将struct用作POD类型,并且,如果他们要添加任何方法,请使用class es。 否则,以下两个片段之间的区别是没有意义的:

class X
{public:// ...
};struct X
{// ...
};

(顺便说一下,这里的一个线程对“ POD类型”的实际含义做了一些很好的解释: C ++中的POD类型是什么? )


#4楼

从C ++ FAQ Lite :

结构的成员和基类默认情况下是公共的,而在类中,它们默认是私有的。 注意:应将基类显式设置为公共,私有或受保护,而不要依赖默认值。

struct和class在功能上是等效的。

好的,足够的干净利落的技术讨论。 从情感上讲,大多数开发人员在类和结构之间做出强烈区分。 结构只是感觉像是一堆开放的位,几乎没有封装或功能性的方式。 班级感觉像是一个有活力的社会成员,拥有智能的服务,强大的封装障碍和明确定义的界面。 因为这是大多数人已经拥有的含义,所以如果您有一个方法很少且具有公共数据的类,则应该使用struct关键字(这种情况确实存在于设计良好的系统中!),但是否则,您可能应该使用该类关键词。


#5楼

我认为Structs旨在作为一种数据结构(如信息的多数据类型数组),而类是为代码打包而设计的(如子例程和函数的集合)。

:(


#6楼

仅当我需要保留一些没有任何关联成员函数的数据(对成员数据进行操作)并直接访问数据变量时,才使用struct。

例如:从文件和套接字流等读取/写入数据。在结构中传递函数参数,在该结构中,函数参数太多而函数语法看起来太长。

从技术上讲,除了默认可访问性之外,类和结构之间没有太大区别。 它的更多内容取决于编程风格,以及如何使用它。


#7楼

从技术上讲,两者在C ++中是相同的-例如,结构可能有重载的运算符等。

但是:

当我希望同时传递多种类型的信息时,我使用结构体;当我处理“功能”对象时,我使用类。

希望能帮助到你。

#include <string>
#include <map>
using namespace std;struct student
{int age;string name;map<string, int> grades
};class ClassRoom
{typedef map<string, student> student_map;public :student getStudentByName(string name) const { student_map::const_iterator m_it = students.find(name); return m_it->second; }private :student_map students;
};

例如,我要在这里的get ...()方法中返回一个struct学生-享受。


#8楼

众所周知,唯一的区别是默认访问权限。 但是当我不希望使用简单的数据类进行任何封装时,即使我实现了一些辅助方法,我也特别使用struct。 例如,当我需要这样的东西时:

struct myvec {int x;int y;int z;int length() {return x+y+z;}
};

#9楼

什么时候选择使用struct,何时选择使用C ++中的类?

定义functorsPOD时使用struct 。 否则,我使用class

// '()' is public by default!
struct mycompare : public std::binary_function<int, int, bool>
{bool operator()(int first, int second){ return first < second; }
};class mycompare : public std::binary_function<int, int, bool>
{
public:bool operator()(int first, int second){ return first < second; }
};

#10楼

如果要编写内部结构为C ++的库,则可以在C ++中使用“结构”,但API可以由C或C ++代码调用。 您只需制作一个包含结构体和全局API函数的标头,就可以像下面这样对C和C ++代码公开这些标头:

// C access Header to a C++ library
#ifdef __cpp
extern "C" {
#endif// Put your C struct's here
struct foo
{...
};
// NOTE: the typedef is used because C does not automatically generate
// a typedef with the same name as a struct like C++.
typedef struct foo foo;// Put your C API functions here
void bar(foo *fun);#ifdef __cpp
}
#endif

然后,您可以使用C ++代码在C ++文件中编写功能bar(),并使其可以从C调用,并且两个世界可以通过声明的结构共享数据。 当混合使用C和C ++时,当然还有其他注意事项,但这是一个简化的示例。


#11楼

现有答案中存在很多误解。

classstruct声明一个类。

是的,您可能必须在类定义中重新排列访问修改关键字,具体取决于您用来声明该类的关键字。

但是,除了语法之外,选择一个而不是另一个的唯一原因是约定/样式/首选项。

对于没有成员函数的类,有些人喜欢使用struct关键字,因为生成的定义“看起来像”来自C的简单结构。

同样,有些人喜欢将class关键字用于具有成员函数和private数据的类,因为它在其上标有“ class”,因此看起来像是他们最喜欢的面向对象编程书中的示例。

现实情况是,这完全取决于您和您的团队,并且对您的程序几乎没有任何影响。

以下两个类在名称上在各个方面都是绝对等效的:

struct Foo
{int x;
};class Bar
{
public:int x;
};

您甚至可以在重新声明时切换关键字:

class Foo;
struct Bar;

(尽管由于不符合, 这会中断Visual Studio的构建 ,所以当您这样做时,编译器将发出警告。)

并且以下表达式均计算为true:

std::is_class<Foo>::value
std::is_class<Bar>::value

不过请注意, 重新定义时不能切换关键字; 这仅仅是因为(按照一定义规则)跨翻译单元的重复类定义必须“由相同的令牌序列组成” 。 这意味着您甚至不能交换const int member;int const member;classstruct的语义无关。


#12楼

当我需要创建POD类型或函子时,我使用结构。


#13楼

类。

默认情况下,班级成员是私人的。

class test_one {int main_one();
};

相当于

class test_one {private:int main_one();
};

所以如果你尝试

int two = one.main_one();

我们将收到一个错误: main_one is private因为它不可访问。 我们可以通过指定一个public来初始化它来解决它

class test_one {public:int main_one();
};

结构。

struct是一类,默认情况下成员是公共的。

struct test_one {int main_one;
};

表示main_one是私有的,即

class test_one {public:int main_one;
};

我将结构用于成员可以取任何值的数据结构,这样更容易。


#14楼

struct优于class的优点是,如果坚持“先公开成员,然后私有”,那么它可以节省一行代码。 因此,我发现关键字class没有用。

这里是另一个原因,仅使用struct ,永不class 。 一些C ++的代码风格指南建议对函数宏使用小写字母,其理由是,将宏转换为内联函数时,无需更改名称。 同样在这里。 您拥有了不错的C样式结构,有一天,您发现需要添加一个构造函数或一些便捷方法。 您将其更改为class吗? 到处?

区分structclass es太麻烦了,进入了做我们应该做的事情的方式-编程。 像许多C ++问题一样,它源于对向后兼容性的强烈渴望。


#15楼

正如其他人指出的

  • 除默认可见性外,两者均等效
  • 无论出于何种原因,都有可能被迫使用一个或另一个

Stroustrup / Sutter明确建议何时使用:

如果类具有不变性,则使用class; 如果数据成员可以独立变化,则使用struct

但是,请记住,向前声明sth是不明智的。 作为一个类( class X; )并将其定义为struct( struct X { ... } )。 它可能在某些链接器(例如g ++)上工作,而在其他链接器(例如MSVC)上失败,因此您会发现自己陷入了开发人员的泥潭。


#16楼

默认情况下,所有类成员都是私有的,默认情况下,所有结构成员都是公共的。 类具有默认的私有基础,而Struct具有默认的公共基础。 在C的情况下,结构不能具有成员函数,而在C ++的情况下,可以将成员函数添加到结构中。 除了这些差异之外,我没有发现任何令人惊讶的地方。


#17楼

C ++中的classstruct之间的区别在于,结构具有默认的public成员和基数,而类具有默认的private成员和基数。 类和结构都可以包含public成员, protected成员和private成员,可以使用继承并可以具有成员函数。

我建议将结构用作没有任何类功能的纯旧数据结构,并建议将类用作具有private数据和成员函数的聚合数据结构。


#18楼

对于C ++,结构和类之间确实没有太大区别。 主要的功能差异在于,结构的成员默认情况下是公共的,而它们在类中默认情况下是私有的。 否则,就语言而言,它们是等效的。

也就是说,我倾向于像在C#中一样在C ++中使用结构,类似于Brian所说的。 结构是简单的数据容器,而类用于除保持数据外还需要对数据进行操作的对象。


#19楼

他们几乎是同一回事。 得益于C ++的魔力,结构可以像类一样保存函数,使用继承,使用“ new”创建等等。

唯一的功能差异是,类从私有访问权限开始,而结构从公共访问权限开始。 这是保持与C的向后兼容性。

实际上,我一直将结构用作数据持有人,将类用作对象。


#20楼

当我的系统正在从另一系统接收固定格式的消息(例如,串行端口)时,该结构对我有用。 您可以将字节流转换为定义字段的结构,然后轻松访问这些字段。

typedef struct
{int messageId;int messageCounter;int messageData;
} tMessageType;void processMessage(unsigned char *rawMessage)
{tMessageType *messageFields = (tMessageType *)rawMessage;printf("MessageId is %d\n", messageFields->messageId);
}

显然,这与您在C中所做的相同,但是我发现必须将消息解码为类的开销通常是不值得的。


#21楼

要回答我自己的问题(无耻地),正如已经提到的那样,访问特权是C ++中它们之间的唯一区别。

我倾向于仅将结构用于数据存储。 如果它使处理数据更加容易,我将允许它获得一些帮助器功能。 但是,一旦数据需要流控制(即保持或保护内部状态的getter / setter)或开始获取任何主要功能(基本上更像对象),它将被“升级”到类中以更好地传达意图。


#22楼

当您要提供具有C ++实现的C兼容接口时,结构( POD ,更一般而言)很方便,因为它们可以跨语言边界和链接器格式移植。

如果您不必担心,那么我认为使用“ struct”而不是“ class”可以很好地传达意图(如@ZeroSignal所述)。 结构还具有更可预测的复制语义,因此它们对于打算写入外部媒体或通过网络发送的数据很有用。

结构对于各种元编程任务也很方便,例如仅公开一堆依赖的typedef的特征模板:

template <typename T> struct type_traits {typedef T type;typedef T::iterator_type iterator_type;...
};

...但这实际上只是利用了struct的默认保护级别是公开的...


#23楼

我从不在C ++中使用“结构”。

我无法想像一个场景,当您想要私有成员时会使用struct,除非您故意要造成混淆。

似乎使用structs更像是如何使用数据的语法指示,但我宁愿仅创建一个类,并尝试以类的名称或通过注释将其明确。

例如

class PublicInputData {//data members};

#24楼

我唯一使用结构而不是类的方法是在函数调用中使用函子之前声明函子,并且为了清楚起见,希望最小化语法。 例如:

struct Compare { bool operator() { ... } };
std::sort(collection.begin(), collection.end(), Compare());

#25楼

尽管可见性的默认值不同,但structclass都是相同的, struct default是public,而class default是private。 您可以通过适当使用privatepublic将其中一个更改为另一个。 它们都允许继承,方法,构造函数,析构函数以及面向对象语言的所有其他优点。

但是,两者之间的巨大区别是C支持关键字struct作为关键字,而class不支持。 这意味着人们可以使用struct中包含文件,可以是#include到无论是C ++或C,只要struct是一个普通的C风格的struct ,并在一切包括文件兼容C,即没有C ++特定关键字例如privatepublic ,没有方法,没有继承等等等。

AC样式struct可与其他接口配合使用,这些接口支持使用C样式struct在接口上来回传输数据。

AC样式struct是一种模板(不是C ++模板,而是一种模式或模板),用于描述内存区域的布局。 多年来,已经创建了可用于C和C插件的接口(在这里为您介绍Java和Python和Visual Basic),其中一些可与C样式struct

什么时候应该在C ++中使用类与结构?相关推荐

  1. Swift中的类和结构体(2)

    Swift中的类和结构体(2) 异变方法 方法调度 影响函数派发方式 异变方法 在Swift中,值类型属性不能被自身的实例方法修改,编译器不会通过编译,报错Left side of mutating ...

  2. java中的类跟结构体_C#中的结构体与类的区别

    经常听到有朋友在讨论C#中的结构与类有什么区别.正好这几日闲来无事,自己总结一下,希望大家指点. 1. 首先是语法定义上的区别啦,这个就不用多说了.定义类使用关键字class 定义结构使用关键字str ...

  3. Swift 中的类和结构体

    Swift 中的结构体的能力被大大加强,不仅可以拥有属性,还以有方法.构造函数.甚至是扩展和遵守协议.这样的结构体和类有很多相同点: 属性:存储数据 方法:提供一些功能 下标:可以使用下标语法 构造器 ...

  4. Swift面向对象基础(上)——Swift中的类和结构体(下)

    2019独角兽企业重金招聘Python工程师标准>>> 学习来自<极客学院> 1 import Foundation 2 3 class User { 4 var nam ...

  5. 7 OC 中class 类的结构

    目录 一 OC 中class 的结构 https://opensource.apple.com/tarballs/objc4/ 在最新的objc源码中 化繁就简来看的话 是以下结构 struct ob ...

  6. Swift 中的类与结构体

  7. 代码生成工具CodeSmith中SchemaExplorer类API文档[转]

    SchemaExplorer中主要类的结构和功能: DatabaseSchema 属性: ConnectionString:一般填写类似于ADO.NET的连接字符串 Name:数据库名称 Provid ...

  8. python 引用文件中的类 报错_Python学习笔记7 头文件的添加规则(转载)

    转载自:https://www.cnblogs.com/taurusfy/p/7605787.html ************************************************ ...

  9. [Swift]枚举、类与结构体的对比

    为什么80%的码农都做不了架构师?>>>    ###枚举.类与结构体的对比### ####枚举与其他两者的关系#### 首先说枚举,相对比较好区分,因为我们知道,枚举与其他两者最大 ...

最新文章

  1. 淘宝Tengine服务器开源
  2. layui 多个文件上传控件 整合缩减代码
  3. [C#] 简单的 Helper 封装 -- RegularExpressionHelper
  4. JavaScript函数节流(throttle)与函数去抖(debounce)解析与应用举例
  5. Matlab生成动态链接库供C#调用
  6. 蛋白粉有什么作用?搭配这些食物帮助提升免疫力!
  7. RIDE在linux系统下运行,在linux上执行robotframework用例
  8. 在Blazor中构建数据库应用程序——第6部分——向天气应用程序添加新记录类型及其UI
  9. 面试时,如何向公司提问?
  10. (转)SegWit 与 Lightning Network
  11. 网站域名后缀index.html的去除方法
  12. 快速乘-在乘法溢出的边缘疯狂试探
  13. 自媒体常用小程序:去水印、配音、文案提取
  14. 关于Java的char类型,字符集,字符编码三者的关系
  15. android xml sax解析,《android用SAX解析xml》
  16. CentOS命令行改色。
  17. javaScript:结合mousedown、mousemove、mouseup事件,实现拖动方块在页面内移动(代码)
  18. 下拉列表之前后端交互
  19. Android自定义不需要焦点的TextView以实现跑马灯效果
  20. MATLAB身份证件号码定位识别

热门文章

  1. Android 圆角矩形ProgressBar
  2. 算法---------寻找重复的子树(Java版本)
  3. Android stdio build.gradle buildscript 里面的repositories 和allprojects里面 repositories 的区别
  4. 电脑卡,eclipse Android stadio 卡,什么都卡解决方法
  5. Android Launcher3(一) -- 启动过程
  6. 【剑指offer-Java版】30最小的K个数
  7. 第十五周程序阅读-范型程序设计(2)
  8. iOS开发之Masonry框架-源码解析
  9. docker 安装vim
  10. Python-装饰器