C#与C++中Class和Struct的类型特性及传参差异问询
C++中Class与Struct实例的类型本质详解
你在测试里发现的现象完全正确——C++里的class和struct本质上几乎没有区别,它们的实例默认都是值类型,传参时都会拷贝,这和C#里的class(引用类型)、struct(值类型)的差异有很大不同。咱们一步步拆解清楚:
一、C++中Class与Struct的核心共性
- 两者都是用户自定义的数据类型,唯一的语法差异只有默认访问权限:
- struct的成员默认是
public - class的成员默认是
private
- struct的成员默认是
- 从内存模型和类型本质来说,它们的实例都是值语义的对象——也就是说,当你创建一个class或struct的实例时,它会直接在栈(或堆,如果你用
new分配)上占用一块内存来存储所有成员变量,没有额外的引用句柄(像C#里的class实例那样)。
二、传参行为的本质:值传递 vs 引用/指针传递
你的测试代码正好完美展示了这一点:
- 对于
TheClass,你用了指针传递(TheClass *c),在函数里修改的是原对象的内存,所以主函数里的testClass被改变了; - 对于
TheStruct,你用了值传递(TheStruct s),函数里的s是原testStruct的一份拷贝,修改拷贝不会影响原对象,所以输出还是"Not Changed"。
如果把StructTaker改成引用传递,效果就和C#里修改class实例一样了:
void StructTaker(TheStruct &s) { // 用引用代替值传递 s.willIChange = "Changed"; }
这时主函数里的testStruct也会被修改,输出变成"Changed"——这说明,不管是class还是struct,只要用引用/指针传递,都能实现类似C#引用类型的修改效果,和它是class还是struct无关。
三、和C#的核心差异对比
你提到的C#里class是引用类型、struct是值类型,这是语言层面的设计差异:
- C#的class实例是在托管堆上分配的,变量存储的是指向实例的引用(类似C++的指针,但由CLR管理);
- C#的struct实例默认在栈上分配(除非作为class成员),变量直接存储实例数据,传参时拷贝。
而C++里没有这种语言层面的区分,所有自定义类型(class/struct)的实例默认都是值语义,是否实现"引用式修改"完全取决于你选择的传参方式(值/引用/指针)。
四、额外补充:风格上的使用惯例
虽然本质一样,但C++社区有不成文的惯例:
- 当类型需要封装(比如有私有成员、成员函数),或者代表一个"实体"(比如
Car、User)时,优先用class; - 当类型只是简单的数据集合(比如坐标
Point、颜色RGB),不需要复杂行为时,优先用struct。
但这只是风格问题,编译器对两者的处理完全一致。
内容的提问来源于stack exchange,提问作者Rakesh Sharma
相关产品推荐
相关产品推荐

