目录
[1.C++ 结构体的基础:存储数据(兼容 C 语言)](#1.C++ 结构体的基础:存储数据(兼容 C 语言))
[1.1定义与使用(C 风格)](#1.1定义与使用(C 风格))
[2.C++ 结构体的扩展:面向对象特性(区别于 C 语言)](#2.C++ 结构体的扩展:面向对象特性(区别于 C 语言))
2.3访问权限控制(public/private/protected)
结构体(Struct)本质上和类(class)几乎一致。
C++ 的结构体是从 C 语言的结构体扩展而来的,它不仅能存储数据(C 语言的特性),还能包含成员函数、构造函数、继承、多态等面向对象特性,仅在默认访问权限和继承权限上有区别。
1.C++ 结构体的基础:存储数据(兼容 C 语言)
C 语言的结构体只能包含数据成员(字段),用于将不同类型的数据封装成一个整体,C++ 完全兼容这一特性,这是结构体最基础的用法。
1.1定义与使用(C 风格)
#include <iostream>
#include <cstring>
using namespace std;
// 定义结构体:封装不同类型的数据
struct Student {
// 数据成员(字段)
char name[20]; // 姓名
int age; // 年龄
float score; // 成绩
};
int main() {
// 1. 创建结构体实例(栈上)
Student s1;
// 赋值:通过.访问成员
strcpy(s1.name, "张三"); // C风格字符串赋值
s1.age = 20;
s1.score = 90.5f;
// 2. 直接初始化(C++11后支持大括号初始化)
Student s2 = {"李四", 21, 88.0f};
// 3. 指针方式创建(堆上)
Student* s3 = new Student;
// 指针访问成员:->
strcpy(s3->name, "王五");
s3->age = 19;
s3->score = 95.0f;
// 输出
cout << "姓名:" << s1.name << ",年龄:" << s1.age << ",成绩:" << s1.score << endl;
cout << "姓名:" << s2.name << ",年龄:" << s2.age << ",成绩:" << s2.score << endl;
cout << "姓名:" << s3->name << ",年龄:" << s3->age << ",成绩:" << s3->score << endl;
// 释放堆内存
delete s3;
s3 = nullptr;
return 0;
}
1.2结构体数组
结构体常用来创建数组,存储一组同类型的结构化数据:
// 定义结构体数组
Student students[3] = {
{"张三", 20, 90.5f},
{"李四", 21, 88.0f},
{"王五", 19, 95.0f}
};
// 遍历数组
for (int i = 0; i < 3; i++) {
cout << "第" << i+1 << "个学生:" << students[i].name << ",年龄:" << students[i].age << endl;
}
2.C++ 结构体的扩展:面向对象特性(区别于 C 语言)
2.1包含成员函数(方法)
结构体中可以定义成员函数,用于操作结构体的数据成员,实现行为封装。
struct Student {
char name[20];
int age;
float score;
// 成员函数:显示学生信息
void ShowInfo() {
cout << "姓名:" << name << ",年龄:" << age << ",成绩:" << score << endl;
}
// 成员函数:修改成绩
void SetScore(float newScore) {
score = newScore;
}
};
// 使用
int main() {
Student s = {"张三", 20, 90.5f};
s.ShowInfo(); // 调用成员函数
s.SetScore(92.0f);
s.ShowInfo(); // 输出修改后的成绩
return 0;
}
2.2构造函数与析构函数
结构体可以定义构造函数 (用于初始化实例)和析构函数(用于清理资源),解决 C 风格结构体初始化繁琐的问题。
#include <string> // 使用C++的string类(更安全)
using namespace std;
struct Student {
// 用C++的string替代char数组,避免内存越界
string name;
int age;
float score;
// 无参构造函数(默认构造函数)
Student() {
name = "未知";
age = 0;
score = 0.0f;
cout << "无参构造函数被调用" << endl;
}
// 有参构造函数(重载)
Student(string n, int a, float s) : name(n), age(a), score(s) {
cout << "有参构造函数被调用" << endl;
}
// 析构函数(清理资源,如堆内存、文件句柄等)
~Student() {
cout << "析构函数被调用:" << name << endl;
}
// 成员函数
void ShowInfo() {
cout << "姓名:" << name << ",年龄:" << age << ",成绩:" << score << endl;
}
};
int main() {
// 调用有参构造函数
Student s1("张三", 20, 90.5f);
s1.ShowInfo();
// 调用无参构造函数
Student s2;
s2.ShowInfo();
// 堆上创建,调用有参构造函数
Student* s3 = new Student("李四", 21, 88.0f);
s3->ShowInfo();
delete s3; // 手动释放,调用析构函数
return 0;
}
1.构造函数名与结构体名相同,无返回值,可以重载(多个参数不同的构造函数)。
2.如果没有手动定义构造函数,编译器会自动生成默认的无参构造函数。
2.3访问权限控制(public/private/protected)
C++ 结构体支持访问权限修饰符,用于控制成员的访问范围(结构体成员默认是public,类成员默认是private,这是和class的第一个区别)。
struct Student {
private: // 私有成员:只能在结构体内部访问
float score; // 成绩私有化,通过成员函数操作
public: // 公共成员:外部可以访问(默认权限)
string name;
int age;
// 构造函数
Student(string n, int a, float s) : name(n), age(a), score(s) {}
// 公共方法:获取私有成员(封装)
float GetScore() {
return score;
}
// 公共方法:修改私有成员(可以添加校验逻辑)
bool SetScore(float newScore) {
if (newScore >= 0 && newScore <= 100) {
score = newScore;
return true;
}
cout << "成绩无效!" << endl;
return false;
}
};
int main() {
Student s("张三", 20, 90.5f);
cout << s.name << "的成绩:" << s.GetScore() << endl;
// s.score = 105; // 错误:私有成员,外部无法直接访问
s.SetScore(105); // 校验失败,输出提示
s.SetScore(95.0f); // 校验成功
cout << s.name << "的新成绩:" << s.GetScore() << endl;
return 0;
}
2.4继承与多态
结构体可以继承其他结构体 / 类,也可以实现多态(通过虚函数),这是和class的第二个区别:结构体的默认继承权限是public,而类是private。
继承:
// 基类:Person
struct Person {
string name;
int age;
Person(string n, int a) : name(n), age(a) {}
void ShowBaseInfo() {
cout << "姓名:" << name << ",年龄:" << age << endl;
}
};
// 派生类:Student 继承 Person(默认public继承)
struct Student : Person {
float score;
// 派生类构造函数:调用基类构造函数
Student(string n, int a, float s) : Person(n, a), score(s) {}
void ShowAllInfo() {
ShowBaseInfo(); // 调用基类方法
cout << "成绩:" << score << endl;
}
};
int main() {
Student s("张三", 20, 90.5f);
s.ShowAllInfo();
// 可以直接访问基类的public成员(因为是public继承)
cout << s.name << endl;
return 0;
}
Person(string n, int a) : name(n), age(a) {}是C++ 中的构造函数初始化列表语法,
name(n)表示将构造函数的参数n赋值给Person的成员变量name,完成name的初始化。
age(a)表示将构造函数的参数a赋值给Person的成员变量age,完成age的初始化。
一般写成下面的形式,但不推荐这种写法,因为多了一次默认初始化的开销,效率更低;对于const成员、引用成员,这种写法直接报错 (因为const和引用必须在初始化时赋值,不能后续赋值)。
struct Person {
string name;
int age;
// 函数体中赋值
Person(string n, int a) {
name = n; // 先默认初始化name,再赋值
age = a; // 先默认初始化age,再赋值
}
};
多态:
struct Person {
string name;
int age;
Person(string n, int a) : name(n), age(a) {}
// 虚函数:允许派生类重写
virtual void ShowInfo() {
cout << "姓名:" << name << ",年龄:" << age << endl;
}
// 虚析构函数:确保派生类析构函数被调用
virtual ~Person() {}
};
struct Student : Person {
float score;
Student(string n, int a, float s) : Person(n, a), score(s) {}
// 重写基类的虚函数
void ShowInfo() override {
cout << "姓名:" << name << ",年龄:" << age << ",成绩:" << score << endl;
}
};
int main() {
// 基类指针指向派生类对象(多态)
Person* p = new Student("张三", 20, 90.5f);
p->ShowInfo(); // 调用Student的ShowInfo(多态效果)
delete p;
return 0;
}
结构体与类的区别总结:

