C++简明教程(10)(初识类)

news/2024/12/27 4:29:20/

类的教程


C++ 类的完整教程

C++ 中,类(class)是面向对象编程的核心概念,用于定义对象的属性(数据成员)和行为(成员函数)。本教程将带你从零开始,循序渐进地学习如何定义和使用类。


1. 类的基本定义

类类似于结构体(struct),但功能更加强大。以下是类的基本定义方法:

#include <iostream>
using namespace std;class Person {
public: // 公有访问修饰符string name; // 数据成员int age;void introduce() { // 成员函数cout << "Hello, my name is " << name << " and I am " << age << " years old." << endl;}
};

注意事项

  1. 类中可以包含数据成员和成员函数。
  2. class 定义的成员默认是 private,而 struct 定义的成员默认是 public

2. 类和对象

类是模板或蓝图,而对象是基于类创建的具体实例。

int main() {Person p; // 创建对象p.name = "Alice";p.age = 25;p.introduce(); // 调用成员函数return 0;
}

运行结果:

Hello, my name is Alice and I am 25 years old.

3. 访问修饰符:public, private, protected

访问修饰符控制类成员的访问权限:

  • public: 公有成员,可被外部访问。
  • private: 私有成员,仅类内部可以访问。
  • protected: 保护成员,通常与继承相关,本教程中不讨论。

示例:

class Person {
private:string secret; // 私有成员public:string name; // 公有成员void setSecret(string s) { // 公有函数secret = s;}void showSecret() {cout << "Secret: " << secret << endl;}
};int main() {Person p;p.name = "Bob";p.setSecret("I love coding."); // 使用公有函数访问私有成员p.showSecret();return 0;
}

运行结果:

Secret: I love coding.

注意事项

  1. 尽量将数据成员声明为 private,通过公有函数访问。
  2. 保护数据成员可以提高代码的安全性。

4. 构造函数

构造函数用于在创建对象时初始化数据成员。它的名字与类名相同,无返回值。

示例代码

class Person {
public:string name;int age;// 构造函数Person(string n, int a) {name = n;age = a;}void introduce() {cout << "Hello, my name is " << name << " and I am " << age << " years old." << endl;}
};int main() {Person p("Charlie", 30); // 调用构造函数p.introduce();return 0;
}

运行结果:

Hello, my name is Charlie and I am 30 years old.

注意事项

  1. 构造函数没有返回值。
  2. 构造函数可以有多个参数。

5. 多种构造函数(构造函数重载)

可以定义多个构造函数以适应不同的初始化需求。

class Person {
public:string name;int age;// 无参构造函数Person() {name = "Unknown";age = 0;}// 带参构造函数Person(string n, int a) {name = n;age = a;}void introduce() {cout << "Hello, my name is " << name << " and I am " << age << " years old." << endl;}
};int main() {Person p1; // 调用无参构造函数Person p2("David", 40); // 调用带参构造函数p1.introduce();p2.introduce();return 0;
}

运行结果:

Hello, my name is Unknown and I am 0 years old.
Hello, my name is David and I am 40 years old.

6. 析构函数

析构函数用于销毁对象时执行清理操作。名字为 ~类名(),无参数和返回值。

class Person {
public:Person() {cout << "Constructor called." << endl;}~Person() {cout << "Destructor called." << endl;}
};int main() {Person p;return 0;
}

运行结果:

Constructor called.
Destructor called.

注意事项

  1. 析构函数在对象生命周期结束时自动调用。
  2. 通常用于释放资源(如动态内存、文件等)。

7. 拷贝构造函数

拷贝构造函数用于用一个对象初始化另一个对象。

class Person {
public:string name;int age;// 构造函数Person(string n, int a) : name(n), age(a) {}// 拷贝构造函数Person(const Person &p) {name = p.name;age = p.age;cout << "Copy constructor called." << endl;}void introduce() {cout << "Hello, my name is " << name << " and I am " << age << " years old." << endl;}
};int main() {Person p1("Eve", 35);Person p2 = p1; // 调用拷贝构造函数p2.introduce();return 0;
}

运行结果:

Copy constructor called.
Hello, my name is Eve and I am 35 years old.

好的,我们继续完成本教程!


8. 运算符重载

运算符重载允许我们为类定义如何使用运算符(如 =< 等)。接下来我们将学习如何重载等号(=)和小于号(<)。

重载等号运算符(=

等号运算符通常用于赋值操作,我们需要重载它以确保正确复制对象的内容。

class Person {
private:string name;int age;public:// 构造函数Person(string n, int a) : name(n), age(a) {}// 重载等号运算符Person& operator=(const Person& p) {if (this == &p) {return *this; // 检查是否是自我赋值}name = p.name;age = p.age;cout << "Assignment operator called." << endl;return *this;}void introduce() {cout << "Hello, my name is " << name << " and I am " << age << " years old." << endl;}
};int main() {Person p1("Alice", 25);Person p2("Bob", 30);p2 = p1; // 调用赋值运算符p2.introduce();return 0;
}

运行结果:

Assignment operator called.
Hello, my name is Alice and I am 25 years old.

重载小于号运算符(<

通常用于比较对象。例如,比较两个对象的某个属性。

class Person {
public:string name;int age;// 构造函数Person(string n, int a) : name(n), age(a) {}// 重载小于号运算符bool operator<(const Person& p) const {return age < p.age; // 按年龄比较}
};int main() {Person p1("Alice", 25);Person p2("Bob", 30);if (p1 < p2) {cout << p1.name << " is younger than " << p2.name << "." << endl;} else {cout << p1.name << " is not younger than " << p2.name << "." << endl;}return 0;
}

运行结果:

Alice is younger than Bob.

9. 成员函数

成员函数是定义在类中的函数,用于操作数据成员。分为 公有成员函数私有成员函数

公有成员函数

公有成员函数可以被类外部调用。

class Person {
public:string name;void introduce() { // 公有成员函数cout << "My name is " << name << "." << endl;}
};

私有成员函数

私有成员函数只能在类内部调用。

class Person {
private:void privateFunction() {cout << "This is a private function." << endl;}public:void callPrivateFunction() {privateFunction(); // 内部调用私有函数}
};int main() {Person p;p.callPrivateFunction();return 0;
}

运行结果:

This is a private function.

10. 静态函数与静态数据成员

静态数据成员

静态数据成员是类的所有对象共享的变量。

class Person {
public:static int population; // 静态数据成员Person() {population++;}~Person() {population--;}static void showPopulation() { // 静态成员函数cout << "Current population: " << population << endl;}
};// 静态数据成员初始化
int Person::population = 0;int main() {Person::showPopulation(); // 访问静态成员函数Person p1, p2;Person::showPopulation();return 0;
}

运行结果:

Current population: 0
Current population: 2

注意事项

  1. 静态数据成员需要在类外初始化。
  2. 静态成员函数只能访问静态数据成员。

11. this 指针

this 指针指向当前对象,用于区分成员变量与形参重名的情况。

class Person {
private:string name;public:void setName(string name) {this->name = name; // 使用 this 指针区分成员变量和参数}void introduce() {cout << "My name is " << this->name << "." << endl;}
};int main() {Person p;p.setName("Alice");p.introduce();return 0;
}

运行结果:

My name is Alice.

12. 总结与注意事项

  1. 类是一种封装机制,通过访问修饰符控制成员访问权限。
  2. 构造函数和析构函数用于管理对象生命周期,特别是动态分配资源时。
  3. 运算符重载使对象更具灵活性,但需要小心处理自我赋值。
  4. 静态成员共享数据,对整个类有效。
  5. this 指针是成员函数内部隐含的指针,指向当前对象。

http://www.ppmy.cn/news/1558431.html

相关文章

挑战一个月基本掌握C++(第十一天)进阶文件,异常处理,动态内存

一 文件和流 如何从文件读取流和向文件写入流。这就需要用到 C 中另一个标准库 fstream&#xff0c;它定义了三个新的数据类型&#xff1a; 数据类型描述ofstream该数据类型表示输出文件流&#xff0c;用于创建文件并向文件写入信息。ifstream该数据类型表示输入文件流&#…

大型语言模型(LLMs)演化树 Large Language Models

大型语言模型&#xff08;LLMs&#xff09;演化树 Large Language Models flyfish 下面的图来自论文地址 Transformer 模型&#xff08;如 BERT 和 GPT-3&#xff09;已经给自然语言处理&#xff08;NLP&#xff09;领域带来了革命性的变化。这得益于它们具备并行化能力&…

【ES6复习笔记】Map(14)

概念 Map 是 JavaScript 中的一种数据结构&#xff0c;它允许你存储键值对&#xff0c;并且可以通过键来访问对应的值。在本教程中&#xff0c;我们将学习如何声明、添加、删除、获取和遍历 Map 集合。 ES6 提供了 Map 数据结构。它类似于对象&#xff0c;也是键值对的集合。…

MFC/C++学习系列之简单记录1——错误解决与Dialog移植

MFC/C学习系列之简单记录1 前言MFC application已停止工作Dialog移植MFC中的去边框设置总结 前言 最近接触MFC&#xff0c;接手一个项目&#xff0c;基于MFC架构编写的&#xff0c;在跑通代码的过程中出现的问题进行简单记录。 MFC application已停止工作 在代码移植过程中&a…

“黄师日报”平安小程序springboot+论文源码调试讲解

第2章 开发环境与技术 基于web的“黄师日报”平安小程序的编码实现需要搭建一定的环境和使用相应的技术&#xff0c;接下来的内容就是对基于web的“黄师日报”平安小程序用到的技术和工具进行介绍。 2.1 MYSQL数据库 本课题所开发的应用程序在数据操作方面是不可预知的&#…

《信管通低代码信息管理系统开发平台》Windows环境安装说明

1 简介 《信管通低代码信息管理系统应用平台》提供多环境软件产品开发服务&#xff0c;包括单机、局域网和互联网。我们专注于适用国产硬件和操作系统应用软件开发应用。为事业单位和企业提供行业软件定制开发&#xff0c;满足其独特需求。无论是简单的应用还是复杂的系统&…

实战分享:开发设计文档模版及编写要点

总框架 一、需求类开发设计文档模版 1、PRD链接 PRD文档链接 2、后端设计 1&#xff09;流程图/代码逻辑描述 描述代码逻辑&#xff0c;要求清晰准确&#xff0c;尽量用图表描述 超过3人天工作量的需求必须有流程图 2&#xff09;库表设计 涉及数据库的改动&#xff0c…

删除VSCode上 origin/分支名,但GitLab上实际上不存在的分支

如果在 Visual Studio Code (VSCode) 中看到的分支在 GitLab 上实际上并不存在&#xff0c;这通常是因为 VSCode 缓存了旧的远程分支信息。以下是一些步骤来解决这个问题&#xff1a; 更新远程引用&#xff1a; 打开 VSCode 的终端&#xff0c;并运行以下命令来更新远程分支的引…