C++中struct和class的区别

C++中struct和class的区别

转自:http://blog.sina.com.cn/s/blog_48f587a80100k630.html

C++中的struct对C中的struct进行了扩充,它已经不再只是一个包含不同数据类型的数据结构了,它已经获取了太多的功能。
struct能包含成员函数吗? 能!
struct能继承吗? 能!!
struct能实现多态吗? 能!!!

 

既然这些它都能实现,那它和class还能有什么区别?

最本质的一个区别就是默认的访问控制,体现在两个方面:

 

1)默认的继承访问权限。struct是public的,class是private的。
你可以写如下的代码:
struct A
{
char a;
};
struct B : A
{
char b;
};

这个时候B是public继承A的。

如果都将上面的struct改成class,那么B是private继承A的。这就是默认的继承访问权限。

 

所以我们在平时写类继承的时候,通常会这样写:
struct B : public A

就是为了指明是public继承,而不是用默认的private继承。

 

当然,到底默认是public继承还是private继承,取决于子类而不是基类。

我的意思是,struct可以继承class,同样class也可以继承struct,那么默认的继承访问权限是看子类到底是用的struct还是class。如下:

 

struct A{};class B : A{}; //private继承
struct C : B{}; //public继承

 

2)struct作为数据结构的实现体,它默认的数据访问控制是public的,而class作为对象的实现体,它默认的成员变量访问控制是private的。

 

注意我上面的用词,我依旧强调struct是一种数据结构的实现体,虽然它是可以像class一样的用。我依旧将struct里的变量叫数据,class内的变量叫成员,虽然它们并无区别。


其实,到底是用struct还是class,完全看个人的喜好,你可以将你程序里所有的class全部替换成struct,它依旧可以很正常的运行。但我给出的最好建议,还是:当你觉得你要做的更像是一种数据结构的话,那么用struct,如果你要做的更像是一种对象的话,那么用class。

 

当然,我在这里还要强调一点的就是,对于访问控制,应该在程序里明确的指出,而不是依靠默认,这是一个良好的习惯,也让你的代码更具可读性。

 

说到这里,很多了解的人或许都认为这个话题可以结束了,因为他们知道struct和class的“唯一”区别就是访问控制。很多文献上也确实只提到这一个区别。

 

但我上面却没有用“唯一”,而是说的“最本质”,那是因为,它们确实还有另一个区别,虽然那个区别我们平时可能很少涉及。那就是:“class”这个关键字还用于定义模板参数,就像“typename”。但关键字“struct”不用于定义模板参数。这一点在Stanley B.Lippman写的Inside the C++ Object Model有过说明。

 

问题讨论到这里,基本上应该可以结束了。但有人曾说过,他还发现过其他的“区别”,那么,让我们来看看,这到底是不是又一个区别。还是上面所说的,C++中的struct是对C中的struct的扩充,既然是扩充,那么它就要兼容过去C中struct应有的所有特性。例如你可以这样写:

 

struct A //定义一个struct
{
char c1;
int n2;
double db3;
};
A a={'p',7,3.1415926}; //定义时直接赋值

 

也就是说struct可以在定义的时候用{}赋初值。那么问题来了,class行不行呢?将上面的struct改成class,试试看。报错!噢~于是那人跳出来说,他又找到了一个区别。我们仔细看看,这真的又是一个区别吗?

 

你试着向上面的struct中加入一个构造函数(或虚函数),你会发现什么?
对,struct也不能用{}赋初值了。


的确,以{}的方式来赋初值,只是用一个初始化列表来对数据进行按顺序的初始化,如上面如果写成A a={'p',7};则c1,n2被初始化,而db3没有。这样简单的copy操作,只能发生在简单的数据结构上,而不应该放在对象上。加入一个构造函数或是一个虚函数会使struct更体现出一种对象的特性,而使此{}操作不再有效。

 

事实上,是因为加入这样的函数,使得类的内部结构发生了变化。而加入一个普通的成员函数呢?你会发现{}依旧可用。其实你可以将普通的函数理解成对数据结构的一种算法,这并不打破它数据结构的特性。

 

那么,看到这里,我们发现即使是struct想用{}来赋初值,它也必须满足很多的约束条件,这些条件实际上就是让struct更体现出一种数据机构而不是类的特性。

 

那为什么我们在上面仅仅将struct改成class,{}就不能用了呢?

其实问题恰巧是我们之前所讲的——访问控制!你看看,我们忘记了什么?对,将struct改成class的时候,访问控制由public变为private了,那当然就不能用{}来赋初值了。加上一个public,你会发现,class也是能用{}的,和struct毫无区别!!!

 

做个总结,从上面的区别,我们可以看出,struct更适合看成是一个数据结构的实现体,class更适合看成是一个对象的实现体。


此文总结的很好,就不用俺总结了,多谢原文作者分享。

<think>嗯,用户问的是C++structclass区别,这确实是一个基础但重要的问题。我需要先回忆一下两者的主要区别,然后组织答案。首先,默认的访问权限应该是关键点,struct默认是public,而class默认是private。接着,继承时的默认访问权限,struct是public继承,class是private。不过用户可能已经知道这些,可能需要更深入的内容。然后想到模板参数中,可以用struct来声明参数,而class不行?或者反过来?可能记混了,需要查证。比如,模板定义时,template<typename T>template<classT>是等效的,但如果是模板模板参数,可能需要用class关键字,struct不行。这点可能需要确认,但用户可能对此不太关心,属于较高级的内容。 另外,C++struct可以像class一样有成员函数、构造函数、继承等,这点C不同。用户可能从C转来,所以需要强调C++struct的增强功能。同时,习惯用法上,struct常用于数据聚合,而class用于更复杂的对象,但这不是语法上的区别,而是约定俗成的。还要注意是否存在其他细微差别,比如关键字在定义模板时的使用,或者友元的处理?可能没有。另外,是否有关于前向声明的区别?例如,前向声明structclass时是否会影响默认的访问权限?例如,声明classA;structA;是否会影响其成员的默认访问权限?应该会,因为前向声明使用struct的话,后续定义时默认访问是public,而class则是private。需要确保引用中的内容是否正确。例如,引用[4]提到更多差异,可能需要参考。例如,关于成员枚举的作用域,structC++中会创建作用域,而C中不会,这点在C++structclass是否一致?应该是一致的,因为C++structclass的主要区别在于默认访问权限继承,其他特性基本相同。 用户可能还关心使用场景,什么时候用struct,什么时候用class。这涉及编程风格,通常struct用于简单数据容器,而class用于封装复杂行为。但需要指出这只是习惯而非强制。另外,是否有C++11/14/17后的新特性影响两者区别?比如聚合初始化,struct如果所有成员都是public,可能更适用聚合初始化,而class如果有private成员则不行。但这也取决于具体的构造函数成员访问权限的设置,不完全是structclass区别,而是访问权限导致的。 需要确保回答准确,避免错误。例如,模板参数中的使用,可能用户会混淆,但实际在模板声明时,typenameclass可以互换,但struct不能用于模板参数声明。例如,template<struct T>是错误的,必须用class或typename。这点需要确认,但可能属于进阶内容,用户可能不需要,但可以提及。 总结,回答的结构应该分点,清晰列出主要区别:默认访问权限、继承时的默认权限、使用习惯,可能还有模板中的使用差异。然后给出使用建议,并附上相关问题。同时,引用中的内容需要正确对应,比如引用[4]提到更多差异,但可能已经涵盖在回答中。需要检查是否有遗漏点,比如友元声明是否有区别?应该没有,structclass在友元声明上是一样的。另外,关于类型名称,前向声明时使用structclass是否会影响类型在代码中的使用?比如,前向声明为struct A后,定义时必须用structA{},还是可以用classA{}?实际上,structclass在定义时是互斥的,前向声明为struct的类型必须用struct定义,否则编译错误。例如:struct A; classA {}; //错误,重复定义或者:classA;struct A{};//错误所以,前向声明必须定义一致,但这是否属于structclass区别呢?可能属于语法要求,但不算两者的差异,而是声明一致性的问题。可能用户不太关心这点,所以可以忽略。 最后,示例代码可能有助于说明,比如定义一个struct一个class,展示默认访问权限的不同。例如:struct MyStruct {intx;//默认public};class MyClass {intx;//默认private};这样用户可以直观看到区别。同时,继承的例子: structDerivedStruct: Base{};//默认public继承class DerivedClass :Base {}; //默认private继承这样对比更明确。 确保回答符合用户的需求,可能用户是初学者,需要明确且简洁的对比,避免过于深入高级话题。同时,相关问题可以涉及使用场景、性能差异(实际上没有)、或者历史原因等。</think>在 C++ 中,`struct` `class` 的核心差异主要体现在默认访问权限继承行为上,以下是具体对比: --- ### **1. 默认访问权限** - **`struct`**:成员继承关系**默认是 `public`** 例如: ```cpp struct MyStruct { int value; // 默认为 public }; ``` - **`class`**:成员继承关系**默认是 `private`** 例如: ```cpp class MyClass { int value; // 默认为 private }; ``` --- ### **2. 默认继承权限** - **`struct` 继承**:默认是 `public` 继承 ```cpp struct DerivedStruct : Base {}; // 等价于 public Base ``` - **`class` 继承**:默认是 `private` 继承 ```cpp class DerivedClass : Base {}; // 等价于 private Base ``` --- ### **3. 使用习惯** - **`struct`**:常用于**数据聚合**(如 POD 类型[^1]),或需要公开所有成员的场景。 例如:坐标点、配置参数等。 ```cpp struct Point { int x, y; void print() { std::cout << x << ", " << y; } }; ``` - **`class`**:用于**封装复杂行为**,强调数据隐藏接口设计。 例如:文件读写器、网络连接等。 ```cpp class FileReader { private: std::string path; public: explicit FileReader(const std::string& p) : path(p) {} std::string read(); }; ``` --- ### **4. 模板参数声明** - 声明模板参数时,`class` `typename` 可互换,但 `struct` **不可用**: ```cpp template <class T> // 合法 template <typename T> // 合法 template <struct T> // 非法! ``` --- ### **5. 前向声明差异** - 前向声明 `struct` 或 `class` 会影响后续定义的默认权限: ```cpp struct A; // 后续定义时必须用 struct,且成员默认 public class B; // 后续定义时必须用 class,且成员默认 private ``` --- ### **总结** - **语法差异**:仅默认访问权限继承行为不同,其他特性(如成员函数、继承、多态)完全一致[^4]。 - **设计意图**:`struct` 强调数据透明性,`class` 强调封装性[^3]。 - **编程规范**:Google C++ 风格指南建议,仅当仅有数据成员时用 `struct`,否则用 `class`[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值