C++中的类和结构体在许多方面具有相似性,都能够封装数据并定义操作这些数据的行为。它们也存在一些微妙的差异,特别是在默认访问权限和继承方面。
一、类和结构体的相似性
1.都可以包含成员函数
类和结构体均可包含任意类型的数据成员(基本类型、自定义类型、指针等),用于封装对象状态。两者都支持数据成员的初始化、引用和修改,且存储方式相同(连续内存布局)。两者均可定义成员函数(包括虚函数、纯虚函数、const
函数),支持函数重载和运算符重载。成员函数通过隐式this
指针访问对象数据,行为完全一致。
class B {
public:
void f() {} // 类内定义成员函数
void g();
};
void B::g() {} // 类外定义成员函数
struct T {
void h() {} // 结构体成员函数
};
2.都支持继承
均支持单继承、多重继承和虚继承,继承层级中可传递成员和方法。派生类/结构体能访问基类的public
和protected
成员,并能重写虚函数
class C : public A { // 类公有继承
public:
using A::A; // 继承构造函数
};
struct U : S { // 结构体默认公有继承
int e;
};
3.都可以使用访问修饰符来控制成员的访问权限
均支持public
、private
、protected
三种访问控制符,语法和语义相同。通过显式声明可覆盖默认权限(类默认private
,结构体默认public
)
class D {
private:
int a; // 仅类内访问
protected:
int b; // 类内和派生类访问
public:
int c; // 任意位置访问
};
struct V {
private:
int d; // 显式私有
public:
int e; // 默认公有
};
4.都可以有构造函数、析构函数以及拷贝构造函数,用于初始化对象、清理资源和复制对象等操作
均支持自定义构造函数(默认构造、拷贝构造、移动构造)、析构函数和初始化列表。
class E {
int* p;
public:
E(int s) : p(new int[s]) {} // 构造函数
~E() { delete[] p; } // 析构函数
};
struct W {
int x, y;
W(int a, int b) : x(a), y(b) {} // 结构体构造函数
};
5.都可以有静态成员变量和静态成员函数
均可定义静态数据成员(需类外初始化)和静态成员函数。静态成员与类/结构体关联而非实例,通过作用域运算符::
访问
class F {
public:
static int c; // 静态成员声明
F() { c++; }
};
int F::c = 0; // 静态成员定义
struct X {
static const int M = 100; // 结构体静态成员
};
6.都可以使用 typedef
或 using
为它们创建别名
均支持typedef
和using
定义内部类型别名,简化复杂类型声明
class G {
public:
typedef int I; // typedef别名
using D = double; // using别名(C++11)
};
struct Y {
typedef char C; // 结构体typedef
using S = std::string; // 结构体using
};
二、类和结构体的不同
1.默认访问权限:
类:默认的访问权限是 private,类中的成员默认对外部不可见,除非显式声明为public。
结构体:默认的访问权限是 public,结构体中的成员默认是对外部可见的。
class MyClass {
int x; // 默认 private
};
struct MyStruct {
int x; // 默认 public
};
2.默认继承权限:
类:继承的默认权限是 private,即派生类成员默认不可访问基类的公有成员,除非显式声明为public或protected。
结构体:继承的默认权限是 public,即派生类成员可以访问基类的公有成员。
class BClass {
public:
int x;
};
class DClass : BClass
{ // 默认 private 继承
// 无法访问 BClass 的成员 x
};
struct BStruct {
int x;
};
struct DStruct : BStruct
{ // 默认 public 继承
// 可以访问 BStruct 的成员 x
};
3.对比:
特性 | 类 | 结构体 | 通俗解释 |
---|---|---|---|
默认访问权限 | private | public | 类成员默认保险箱锁着,结构体成员默认开箱即用 |
默认继承权限 | private | public | 类继承默认"内部消化",结构体继承默认"全家共享" |