C++作为支持面向对象编程的语言,结构体struct和类class都是实现封装、继承、多态特性的重要载体,但两者在默认行为和适用场景上有明显不同,下面先介绍核心差异。

默认访问权限的区别
struct和class最直观的差异是成员的默认访问权限不同,这是两者最核心的区别之一。
- struct的成员默认访问权限是public,也就是说没有显式声明访问修饰符的成员,外部可以直接访问。
- class的成员默认访问权限是private,没有显式声明访问修饰符的成员,只能在类内部访问,外部无法直接调用。
下面通过代码示例验证这个差异:
#include <iostream>
using namespace std;
// 结构体,成员默认public
struct MyStruct {
int a; // 默认public
void print() { // 默认public
cout << "struct a: " << a << endl;
}
};
// 类,成员默认private
class MyClass {
int b; // 默认private
void print() { // 默认private
cout << "class b: " << b << endl;
}
public:
void setB(int val) {
b = val;
print();
}
};
int main() {
MyStruct s;
s.a = 10; // 可以直接访问,编译通过
s.print(); // 可以直接调用,编译通过
MyClass c;
// c.b = 20; 编译报错,b是private成员
// c.print(); 编译报错,print是private成员
c.setB(20); // 通过public接口访问,编译通过
return 0;
}
默认继承方式的区别
除了成员访问权限,struct和class的默认继承方式也存在差异,这个差异在继承场景下会体现出来。
- struct默认的继承方式是public继承,派生类会继承基类的public成员为public,protected成员为protected。
- class默认的继承方式是private继承,派生类会继承基类的public和protected成员都变为private。
来看继承场景的代码示例:
#include <iostream>
using namespace std;
struct BaseStruct {
int pub_val;
protected:
int pro_val;
};
class BaseClass {
public:
int pub_val;
protected:
int pro_val;
};
// struct继承struct,默认public继承
struct DeriveStruct : BaseStruct {
void test() {
pub_val = 10; // 可访问,pub_val是public
pro_val = 20; // 可访问,pro_val是protected
}
};
// class继承class,默认private继承
class DeriveClass : BaseClass {
void test() {
pub_val = 10; // 可访问,在类内部private继承的成员仍可访问
pro_val = 20; // 可访问,在类内部private继承的成员仍可访问
}
};
int main() {
DeriveStruct ds;
ds.pub_val = 10; // 编译通过,pub_val是public
DeriveClass dc;
// dc.pub_val = 10; 编译报错,private继承后pub_val变为private
return 0;
}
适用场景的差异
在实际开发中,struct和class的适用场景也有比较明确的划分:
- struct更适合用来封装简单的数据集合,比如坐标、配置项等不需要复杂逻辑的场景,默认public的特性方便直接访问数据成员。
- class更适合实现面向对象的封装特性,需要隐藏内部实现细节,只暴露公共接口的场景,默认private的特性符合封装的要求。
面向对象基础的关联理解
struct和class都是C++面向对象特性的载体,面向对象的三大特性封装、继承、多态两者都支持:
- 封装:两者都支持将数据和操作数据的函数封装在一起,区别只是默认的访问权限不同。
- 继承:两者都支持继承其他结构体或类,只是默认继承方式不同。
- 多态:两者都支持虚函数,都可以实现运行时多态,比如下面的示例:
#include <iostream>
using namespace std;
// struct也可以有虚函数
struct Base {
virtual void show() {
cout << "Base show" << endl;
}
virtual ~Base() {} // 虚析构函数
};
struct Derive : Base {
void show() override {
cout << "Derive show" << endl;
}
};
int main() {
Base* ptr = new Derive();
ptr->show(); // 输出Derive show,实现多态
delete ptr;
return 0;
}
总结来说,struct和class的核心区别仅在于默认的访问权限和继承方式,功能上几乎没有差异。如果是简单的数据聚合场景可以优先使用struct,如果需要实现严格的封装逻辑则优先使用class,开发者可以根据实际需求灵活选择。