在哪种情况下,在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楼
结构的成员和基类默认情况下是公共的,而在类中,它们默认是私有的。 注意:应将基类显式设置为公共,私有或受保护,而不要依赖默认值。
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 ++中的类?
定义functors
和POD
时使用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楼
现有答案中存在很多误解。
是的,您可能必须在类定义中重新排列访问修改关键字,具体取决于您用来声明该类的关键字。
但是,除了语法之外,选择一个而不是另一个的唯一原因是约定/样式/首选项。
对于没有成员函数的类,有些人喜欢使用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;
与class
或struct
的语义无关。
#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
吗? 到处?
区分struct
和class
es太麻烦了,进入了做我们应该做的事情的方式-编程。 像许多C ++问题一样,它源于对向后兼容性的强烈渴望。
#15楼
正如其他人指出的
- 除默认可见性外,两者均等效
- 无论出于何种原因,都有可能被迫使用一个或另一个
Stroustrup / Sutter明确建议何时使用:
但是,请记住,向前声明sth是不明智的。 作为一个类( class X;
)并将其定义为struct( struct X { ... }
)。 它可能在某些链接器(例如g ++)上工作,而在其他链接器(例如MSVC)上失败,因此您会发现自己陷入了开发人员的泥潭。
#16楼
默认情况下,所有类成员都是私有的,默认情况下,所有结构成员都是公共的。 类具有默认的私有基础,而Struct具有默认的公共基础。 在C的情况下,结构不能具有成员函数,而在C ++的情况下,可以将成员函数添加到结构中。 除了这些差异之外,我没有发现任何令人惊讶的地方。
#17楼
C ++中的class
和struct
之间的区别在于,结构具有默认的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楼
尽管可见性的默认值不同,但struct
和class
都是相同的, struct
default是public,而class
default是private。 您可以通过适当使用private
和public
将其中一个更改为另一个。 它们都允许继承,方法,构造函数,析构函数以及面向对象语言的所有其他优点。
但是,两者之间的巨大区别是C支持关键字struct
作为关键字,而class
不支持。 这意味着人们可以使用struct
中包含文件,可以是#include
到无论是C ++或C,只要struct
是一个普通的C风格的struct
,并在一切包括文件兼容C,即没有C ++特定关键字例如private
, public
,没有方法,没有继承等等等。
AC样式struct
可与其他接口配合使用,这些接口支持使用C样式struct
在接口上来回传输数据。
AC样式struct
是一种模板(不是C ++模板,而是一种模式或模板),用于描述内存区域的布局。 多年来,已经创建了可用于C和C插件的接口(在这里为您介绍Java和Python和Visual Basic),其中一些可与C样式struct
。