【面试分享】C++ 中结构体(struct)和类(class)的区别
- 在 C++中,结构体(
struct
)和类(class
)有一些相似之处,但也存在一些重要的区别:
一、默认访问权限
-
结构体:
- 在 C++中,结构体的默认成员访问权限是
public
(公有)。这意味着在结构体中定义的成员变量和成员函数在默认情况下是可以被外部直接访问的。 - 例如:
struct MyStruct { int x; // 默认是公有成员 void printX() { std::cout << "x = " << x << std::endl; } }; int main() { MyStruct s; s.x = 10; s.printX(); return 0; }
- 在这个例子中,可以直接访问结构体
MyStruct
的成员变量x
,并调用成员函数printX
。
- 在 C++中,结构体的默认成员访问权限是
-
类:
- 类的默认成员访问权限是
private
(私有)。这意味着在类中定义的成员变量和成员函数在默认情况下是不能被外部直接访问的,需要通过公有成员函数来进行访问。 - 例如:
class MyClass { int x; // 默认是私有成员 public: void setX(int value) { x = value; } int getX() { return x; } }; int main() { MyClass c; // c.x = 10; // 错误,不能直接访问私有成员 c.setX(10); std::cout << "x = " << c.getX() << std::endl; return 0; }
- 在这个例子中,不能直接访问类
MyClass
的成员变量x
,需要通过公有成员函数setX
和getX
来进行设置和获取。
- 类的默认成员访问权限是
二、继承方式
-
结构体继承:
- 当结构体从另一个结构体或类继承时,默认的继承方式是
public
继承。这意味着基类的公有成员和保护成员在派生结构体中仍然是公有和保护成员。 - 例如:
struct Base { int x; }; struct Derived : Base { void printX() { std::cout << "x = " << x << std::endl; } }; int main() { Derived d; d.x = 10; d.printX(); return 0; }
- 在这个例子中,派生结构体
Derived
从基类Base
以公有继承方式继承,所以可以直接访问基类的成员变量x
。
- 当结构体从另一个结构体或类继承时,默认的继承方式是
-
类继承:
- 当类从另一个类继承时,默认的继承方式是
private
继承。这意味着基类的公有成员和保护成员在派生类中变为私有成员。 - 例如:
class Base { int x; public: void setX(int value) { x = value; } }; class Derived : private Base { public: void printX() { // std::cout << "x = " << x; // 错误,不能直接访问私有成员 setX(10); std::cout << "x = " << Base::x; // 通过基类的公有成员函数设置私有成员的值,然后通过强制转换访问私有成员,这种方式不推荐 } }; int main() { Derived d; // d.x = 10; // 错误,不能直接访问私有成员 d.printX(); return 0; }
- 在这个例子中,派生类
Derived
从基类Base
以私有继承方式继承,不能直接访问基类的成员变量x
,需要通过基类的公有成员函数来进行设置和获取。
- 当类从另一个类继承时,默认的继承方式是
三、用途和设计理念
-
结构体用途:
- 结构体通常用于表示简单的数据集合,这些数据之间没有太多的逻辑关系。结构体的设计理念更侧重于数据的封装和组织,而不是行为的封装。
- 例如,可以使用结构体来表示一个点的坐标(
x
和y
)、一个颜色的 RGB 值(red
、green
、blue
)等。
-
类用途:
- 类通常用于表示具有复杂行为和状态的对象。类的设计理念更侧重于行为的封装和对象的抽象,通过定义成员函数来实现对象的行为和操作。
- 例如,可以使用类来表示一个图形对象(如矩形、圆形等),这些对象具有属性(如位置、大小、颜色等)和行为(如绘制、移动、缩放等)。
- 总之,结构体和类在 C++中都有各自的用途和特点。在选择使用结构体还是类时,需要根据具体的需求和设计理念来决定。如果只是需要简单的数据封装和组织,可以使用结构体;如果需要实现复杂的行为和状态封装,可以使用类。