C++ 类和对象:面向对象编程基础
目录标题
- 1. 什么是类?
- 2. 什么是对象?
- 3. 如何定义一个类?
- 4. 如何创建对象?
- 5. 类的构造函数
- 6. 类的析构函数
- 7. 数据封装和访问修饰符
- 8. 示例:一个简单的`BankAccount`类
- 9. 使用g++编译
- 10. 再来一个简单的C++程序
- 11. 定义书籍类 `Book`
- 12. 实现书籍类的成员函数
- 13. 使用书籍类
- 14. 编译和运行
- 15. 再来一个例子
- 16. 定义账户类 `Account`
- 17. 实现账户类 `Account`
- 18. 定义银行类 `Bank`
- 19. 实现银行类 `Bank`
- 20. 使用`Account`和`Bank`类
- 21. 编译和运行
- 22. 拓展:std::string getTitle() const; 这里的std是什么意思?
面向对象编程(Object-Oriented Programming,OOP)是一种编程范式,它使用“对象”来设计软件。在C++中,对象是通过类来创建的。类是创建对象的蓝图或模板。
1. 什么是类?
类是一种用户定义的数据类型,它拥有数据成员和成员函数。数据成员用于存储与类相关的信息,而成员函数则用于操作这些数据。类可以看作创建对象的模板。
2. 什么是对象?
对象是类的实例。一旦定义了类,我们可以通过类创建对象,对象包含了类中定义的数据成员和成员函数。
3. 如何定义一个类?
C++中类的定义以关键字class
开始,后跟类名和类体。类体包含在一对花括号中。通常,类的定义会放在头文件中,例如.h
或.hpp
文件。
// BankAccount.h
class BankAccount {
public:// 构造函数BankAccount(double balance);// 成员函数void deposit(double amount);void withdraw(double amount);double getBalance() const;private:// 数据成员double balance;
};
4. 如何创建对象?
创建类的对象非常简单,只需像声明普通变量一样声明对象即可。
BankAccount myAccount(50.0);
5. 类的构造函数
构造函数是一种特殊的成员函数,它在创建对象时自动调用。构造函数的名称与类名相同。
// BankAccount.cpp
BankAccount::BankAccount(double initialBalance) : balance(initialBalance) {if (initialBalance < 0) {balance = 0;// 报告错误:初始余额不能为负}
}
6. 类的析构函数
析构函数是另一种特殊的成员函数,它在对象销毁时自动调用。析构函数的名称是在类名前加上一个波浪号~
。
7. 数据封装和访问修饰符
封装是面向对象编程的一个重要特征,它防止了对对象内部的直接访问。在C++中,我们通过访问修饰符public
、protected
和private
来实现封装。
8. 示例:一个简单的BankAccount
类
让我们来看一个完整的例子,它定义了一个BankAccount
类和相关的成员函数。
// BankAccount.hclass BankAccount {
public:BankAccount(double balance);void deposit(double amount);void withdraw(double amount);double getBalance() const;private:double balance;
};// BankAccount.cpp#include "BankAccount.h"BankAccount::BankAccount(double initialBalance) : balance(initialBalance) {if (initialBalance < 0) {balance = 0;// 报告错误:初始余额不能为负}
}void BankAccount::deposit(double amount) {if (amount > 0) {balance += amount;} else {// 报告错误:存款金额必须大于0}
}void BankAccount::withdraw(double amount) {if (amount > balance) {// 报告错误:不能透支账户} else {balance -= amount;}
}double BankAccount::getBalance() const {return balance;
}// main.cpp#include <iostream>
#include "BankAccount.h"int main() {BankAccount myAccount(100.0);myAccount.deposit(50.0);myAccount.withdraw(25.0);std::cout << "当前余额: $" << myAccount.getBalance() << std::endl;return 0;
}
在这个例子中,我们创建了一个BankAccount
类,它有一个构造函数,两个操作余额的函数deposit
和withdraw
,以及一个查询余额的函数getBalance
。这个类的私有数据成员balance
用于存储账户余额。
9. 使用g++编译
要使用g++
编译上述示例,需要确保所有的源文件(.cpp
)和头文件(.h
)都在同一个目录下。
- 使用
g++
编译器编译BankAccount.cpp
和main.cpp
文件。
g++ -c BankAccount.cpp
g++ -c main.cpp
这两个命令分别编译了BankAccount.cpp
和main.cpp
文件,并生成了对应的目标文件(.o
文件)。
- 接下来,链接这些目标文件以生成最终的可执行文件。使用以下命令:
g++ BankAccount.o main.o -o BankAccountApp
这个命令将BankAccount.o
和main.o
文件链接在一起,并创建了一个名为BankAccountApp
的可执行文件。
- 运行生成的可执行文件:
./BankAccountApp
如果一切顺利,应该会看到程序输出的当前余额。
完整的编译和运行命令序列如下:
g++ -c BankAccount.cpp
g++ -c main.cpp
g++ BankAccount.o main.o -o BankAccountApp
./BankAccountApp
当前余额: $125
如果希望一步完成编译和链接,可以使用以下命令:
g++ BankAccount.cpp main.cpp -o BankAccountApp
这个命令会同时编译和链接所有的.cpp
文件,并生成一个名为BankAccountApp
的可执行文件。然后,可以运行这个可执行文件来查看程序的输出。
10. 再来一个简单的C++程序
再创建一个简单的C++程序,这次我们将实现一个书籍类(Book
)。这个类将包含一些基本属性,如标题、作者和出版年份,并提供一些成员函数来访问和修改这些属性。
11. 定义书籍类 Book
首先,我们将定义一个名为 Book
的类,它将具有三个私有成员:标题(title
)、作者(author
)和出版年份(publishYear
)。我们还将提供公共函数来构造书籍、设置和获取这些属性。
// Book.h
#ifndef BOOK_H
#define BOOK_H#include <string>class Book {
public:// 构造函数Book(const std::string& title, const std::string& author, int publishYear);// 成员函数void setTitle(const std::string& title);void setAuthor(const std::string& author);void setPublishYear(int year);std::string getTitle() const;std::string getAuthor() const;int getPublishYear() const;private:std::string title;std::string author;int publishYear;
};#endif
12. 实现书籍类的成员函数
接下来,我们实现这个类的成员函数。这些函数包括构造函数、设置和获取属性的函数。
// Book.cpp
#include "Book.h"Book::Book(const std::string& title, const std::string& author, int publishYear): title(title), author(author), publishYear(publishYear) {}void Book::setTitle(const std::string& title) {this->title = title;
}void Book::setAuthor(const std::string& author) {this->author = author;
}void Book::setPublishYear(int year) {this->publishYear = year;
}std::string Book::getTitle() const {return title;
}std::string Book::getAuthor() const {return author;
}int Book::getPublishYear() const {return publishYear;
}
13. 使用书籍类
最后,我们将在 main
函数中创建和使用 Book
类的实例。
// main.cpp
#include <iostream>
#include "Book.h"int main() {// 创建 Book 类的一个对象Book myBook("1984", "George Orwell", 1949);// 输出书籍信息std::cout << "Book: " << myBook.getTitle() << std::endl;std::cout << "Author: " << myBook.getAuthor() << std::endl;std::cout << "Publish Year: " << myBook.getPublishYear() << std::endl;// 修改书籍信息myBook.setTitle("Animal Farm");myBook.setAuthor("George Orwell");myBook.setPublishYear(1945);// 输出修改后的书籍信息std::cout << "Updated Book: " << myBook.getTitle() << std::endl;std::cout << "Updated Author: " << myBook.getAuthor() << std::endl;std::cout << "Updated Publish Year: " << myBook.getPublishYear() << std::endl;return 0;
}
14. 编译和运行
为了编译和运行这个程序,你可以使用类似之前的 g++
命令:
g++ Book.cpp main.cpp -o BookApp
./BookApp
Book: 1984
Author: George Orwell
Publish Year: 1949
Updated Book: Animal Farm
Updated Author: George Orwell
Updated Publish Year: 1945
这会编译你的程序并生成一个可执行文件 BookApp
,运行这个可执行文件将显示书籍信息和更新后的信息。
15. 再来一个例子
让我们设计一个更具交互性的例子,这次我们将创建一个简单的银行账户系统。这个系统会包含两个类:Account
和Bank
。Account
类将用于处理单个银行账户的基本信息和操作,如存款、取款和查询余额,而Bank
类将管理多个账户并允许添加新账户。
16. 定义账户类 Account
首先,我们定义一个Account
类,它包含账户的基本信息和操作。
// Account.h
#ifndef ACCOUNT_H
#define ACCOUNT_H#include <string>class Account {
public:Account(const std::string& owner, double balance);void deposit(double amount);bool withdraw(double amount);double getBalance() const;std::string getOwner() const;private:std::string owner;double balance;
};#endif
17. 实现账户类 Account
现在,我们来实现Account
类的成员函数。
// Account.cpp
#include "Account.h"Account::Account(const std::string& owner, double balance): owner(owner), balance(balance) {}void Account::deposit(double amount) {if (amount > 0) {balance += amount;}
}bool Account::withdraw(double amount) {if (amount > 0 && amount <= balance) {balance -= amount;return true;}return false;
}double Account::getBalance() const {return balance;
}std::string Account::getOwner() const {return owner;
}
18. 定义银行类 Bank
接着,我们定义一个Bank
类来管理多个Account
。
// Bank.h
#ifndef BANK_H
#define BANK_H#include "Account.h"
#include <vector>class Bank {
public:void addAccount(const Account& account);void printAccounts() const;private:std::vector<Account> accounts;
};#endif
19. 实现银行类 Bank
最后,我们实现Bank
类的功能。
// Bank.cpp
#include "Bank.h"
#include <iostream>void Bank::addAccount(const Account& account) {accounts.push_back(account);
}void Bank::printAccounts() const {for (const auto& account : accounts) {std::cout << "Owner: " << account.getOwner() << ", Balance: $" << account.getBalance() << std::endl;}
}
20. 使用Account
和Bank
类
最后,我们在main
函数中使用这些类。
// main.cpp
#include "Account.h"
#include "Bank.h"int main() {Account a1("John Doe", 1000);Account a2("Jane Doe", 1500);Bank bank;bank.addAccount(a1);bank.addAccount(a2);bank.printAccounts();return 0;
}
21. 编译和运行
同样地,使用g++
将这些文件编译成一个可执行文件:
g++ Account.cpp Bank.cpp main.cpp -o BankSystem
./BankSystem
Owner: John Doe, Balance: $1000
Owner: Jane Doe, Balance: $1500
运行这个指令后,你将看到输出的账户信息,这表明我们的简易银行系统能够管理多个账户并打印它们的信息。
22. 拓展:std::string getTitle() const; 这里的std是什么意思?
在C++中,std
是标准命名空间(standard namespace)的名称,它是由C++标准库定义的。命名空间是一种将全局作用域分割的机制,用于解决命名冲突的问题,特别是当不同的库可能包含相同名称的标识符时。
在C++中,标准库中的所有组件(如 std::string
、std::vector
、std::cout
等)都被定义在 std
命名空间中。因此,当你在代码中看到 std::
前缀时,它表明你正在使用的标识符是标准库的一部分。
例如,std::string
是一个类,它提供了字符串的功能,而 std::cout
是一个对象,用于向标准输出流(通常是控制台)输出数据。
在你的代码示例中,std::string getTitle() const;
是一个成员函数声明,它返回一个 std::string
类型的值。这意味着 getTitle
函数将返回一个字符串,这个字符串是标准库中的 string
类型。const
关键字表示这个函数不会修改调用它的对象的状态,即它是一个“只读”函数。
当你在代码中使用标准库的组件时,你需要使用 std::
前缀,除非你已经通过 using
指令导入了特定的名称到当前作用域中。例如:
#include <string> // 包含string头文件// 使用std::string,因为还没有导入到当前作用域
void someFunction() {std::string myString = "Hello, world!";
}// 使用using指令导入std::string到当前作用域
using std::string;void anotherFunction() {string anotherString = "Another message!"; // 不需要std::前缀
}
在 anotherFunction
中,由于我们已经使用 using
指令导入了 std::string
,所以可以直接使用 string
而不需要 std::
前缀。然而,在 someFunction
中,我们没有导入 std::string
,所以我们必须使用 std::string
。
相关文章:

C++ 类和对象:面向对象编程基础
目录标题 1. 什么是类?2. 什么是对象?3. 如何定义一个类?4. 如何创建对象?5. 类的构造函数6. 类的析构函数7. 数据封装和访问修饰符8. 示例:一个简单的BankAccount类9. 使用g编译10. 再来一个简单的C程序11. 定义书籍类…...

linux 基础命令使用
命令 su 用于切换到另一个用户身份,通常是超级用户(root)。su命令可以用来在命令行下切换用户,也可以在脚本中使用。 语法: su [选项] [用户名] 选项: - -c:执行完命令后,立即退出su命令;…...

eve 导入linux
mkdir /opt/unetlab/addons/qemu/linux-centos7 cd /opt/unetlab/addons/qemu/linux-centos7 上传hda.qcow2 /opt/unetlab/wrappers/unl_wrapper -a fixpermissions Linux images - (eve-ng.net) Due to very high demand of this section and problems with how to crea…...

vivado新版本兼容老版本,vitis classic兼容sdk教程
new version: vivado版本2023.2 和vitisv classic 2023.2 old version: vivado 2018.3以及之前的版本 打开工程 自动升级到当前版本,选择OK 点击Yes,合并当前的目录架构 点击OK 点击Report IP status 勾选要升级的IP核,点击升级 在项目工程文件夹…...

02.02.返回倒数第k个节点
实现一种算法,找出单向链表中倒数第 k 个节点。返回该节点的值。 注意:本题相对原题稍作改动 示例: 输入: 1->2->3->4->5 和 k 2 输出: 4 说明: 给定的 k 保证是有效的。 代码ÿ…...

MongoDB 从部署到掌握
一、docker部署MongoDB ## 通过docker安装MongoDB~~~shell #拉取镜像 docker pull mongo:4.0.3#创建容器 docker create --name mongodb-server -p 27017:27017 -v mongodb-data:/data/db mongo:4.0.3 --auth#启动容器 docker start mongodb-server#进入容器 docker exec -it …...

electron-vite工具打包后通过内置配置文件动态修改接口地址实现方法
系列文章目录 electronvitevue3 快速入门教程 文章目录 系列文章目录前言一、实现过程二、代码演示1.resources/env.json2.App.vue3.main/index.js4.request.js5.安装后修改 前言 使用electron-vite 工具开发项目打包完后每次要改接口地址都要重新打包,对于多环境…...

每日一练2024.5.9
题目: 给定一副牌,每张牌上都写着一个整数。 此时,你需要选定一个数字 X,使我们可以将整副牌按下述规则分成 1 组或更多组: 每组都有 X 张牌。组内所有的牌上都写着相同的整数。 仅当你可选的 X > 2 时返回 tru…...

P2622 关灯问题
小小注解: 1. vis:表示到达该状态的步数(min)1, 因为我们是从开始状态 穷举,所以每次到一个新状态(之前没有到过的状态)就是最小步数。 如何判断是否是一个新状态呢,…...

从头开始的建材类电商小程序开发指南
在当今数字化时代,小程序已经成为了许多企业推广和销售的重要渠道。对于建筑材料行业来说,开发一个属于自己的小程序商城不仅可以提升产品曝光度,还可以提供更好的用户购物体验。下面,我们将逐步教你如何开发建筑材料行业小程序。…...

数据结构中的栈(C语言版)
一.栈的概念 栈是一种常见的数据结构,它遵循后进先出的原则。栈可以看作是一种容器,其中的元素按照一种特定的顺序进行插入和删除操作。 压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。 出栈:栈的删除操作叫做…...

(贪心05) 无重叠区间 划分字母区间 合并区间
一、无重叠区间 力扣第435题 第一种方法: 个人思路: 按照区间左边界排序,然后从左开始遍历,每遍历到一个区间就要保证该区间之前的集合为不重叠区间(贪心,局部最优解)。 难点在于如何把新遍历…...

简单网络管理协议(SNMP)入门
目录 概述 SMI(对象命名、数据类型、编码方法) 对象命名 数据类型 编码方法 MIB(版本、分组、对象定义、变量访问) 版本 分组 对象定义 变量访问 SNMP 实现机制与报文分析 协议操作 报文格式 实现机制 验证分析 SN…...

leetcode解题思路分析(一百五十七)1366 - 1372 题
通过投票对团队排名 现在有一个特殊的排名系统,依据参赛团队在投票人心中的次序进行排名,每个投票者都需要按从高到低的顺序对参与排名的所有团队进行排位。 排名规则如下: 参赛团队的排名次序依照其所获「排位第一」的票的多少决定。如果存在…...

药物代谢动力学学习笔记
一、基本概念 二、经典房室模型 三、非线性药物代谢动力学 四、非房室模型 五、药代动力学与药效动力学 六、生物等效性评价 七、生物样品分析方法 基本概念 生物样品:生物机体的全血、血浆、血清、粪便、尿液或其他组织的样品 特异性,specificity&…...

IDEA中git的常用操作(保姆级教学)
IDEA中git的常用操作(保姆级教学) 以下是git的工作原理,觉得繁琐的可以跳过不看 Workspace:工作区 (平时存放代码的地方) Index / Stage:暂存区(用于临时存放存放你的改动,事实上就是一个文件&…...

保研面试408复习 3——操作系统
文章目录 1、操作系统一、进程有哪几种状态,状态之间的转换、二、调度策略a.处理机调度分为三级:b.调度算法 标记文字记忆,加粗文字注意,普通文字理解。 为什么越写越少? 问就是在打瓦。(bushi) 1、操作系统 一、进程…...

【代码随想录37期】Day02 有序数组的平方、长度最小的子数组、螺旋矩阵Ⅱ(施工中)
有序数组的平方 977. 有序数组的平方 - 力扣(LeetCode) v1.0:直接暴力 4分半做出来,用sort api class Solution { public:vector<int> sortedSquares(vector<int>& nums) {vector<int> result;for(int i 0; i<…...

通俗的理解网关的概念的用途(三):你的数据包是如何到达下一层的
其实,这一章我写不好,因为这其中会涉及到一些计算和一些广播等概念,本人不善于此项。在此略述,可以参考。 每台设备的不同连接在获得有效的IP地址后,会根据IP地址的规则和掩码的规则,在操作系统和交换机&a…...

基于Springboot的校运会管理系统(有报告)。Javaee项目,springboot项目。
演示视频: 基于Springboot的校运会管理系统(有报告)。Javaee项目,springboot项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结构&a…...

USP技术提升大语言模型的零样本学习能力
大语言模型(LLMs)在零样本和少样本学习能力上取得了显著进展,这通常通过上下文学习(in-context learning, ICL)和提示(prompting)来实现。然而,零样本性能通常较弱,因为缺…...

前端安全防护实战:XSS、CSRF防御与同源策略详解(react 案例)
前端安全防护实战中,主要涉及三个方面:XSS (Cross-Site Scripting) 攻击的防御、CSRF (Cross-Site Request Forgery) 攻击的防御,以及浏览器的同源策略。以下是这三个方面的详细说明: XSS 防御详解 XSS 概述 XSS攻击是一种让攻…...

2024C题生物质和煤共热解问题的研究 详细思路
背景 随着全球能源需求的不断增长和对可再生能源的追求,生物质和煤共热解作为一种潜在的能源转化技术备受关注。生物质是指可再生能源,源自植物和动物的有机物质,而煤则是一种化石燃料。** 在共热解过程中,生物质和煤在高温和缺氧…...

智慧旅游引领未来风尚,科技助力旅行更精彩:科技的力量推动旅游业创新发展,为旅行者带来更加便捷、高效和智能的旅行服务
目录 一、引言 二、智慧旅游的概念与特点 (一)智慧旅游的概念 (二)智慧旅游的特点 三、科技推动旅游业创新发展 (一)大数据技术的应用 (二)人工智能技术的应用 (…...

十.吊打面试官系列-Tomcat优化-通过压测Tomcat调优实战
前言 上一篇文章我们讲解了一下Tomcat底层的结构和执行原理,我们需要重点去掌握的是Tomcat的高内聚低耦合的设计,以及责任链模式,以及Tomcat NIO编程模式,这些是Tomcat比较核心的点,本篇文章我们将对Tomcat的参数做一…...

JVM调优—减少FullGC
背景 最近负责了一个审批流程新项目,带领了几个小伙伴,哼哧哼哧的干了3个月左右,终于在三月底完美上线了,好消息是线上客户用的很丝滑,除了几个非常规的业务提单之外,几乎没有什么大的问题,但是…...

力扣 256. 粉刷房子 LCR 091. 粉刷房子 python AC
动态规划 class Solution:def minCost(self, costs):row, col len(costs), 3dp [[0] * col for _ in range(row 1)]for i in range(1, row 1):for j in range(col):dp[i][j] costs[i - 1][j - 1]if j 0:dp[i][j] min(dp[i - 1][1], dp[i - 1][2])elif j 1:dp[i][j] m…...

C++STL细节,底层实现,面试题04
文章目录 19. STL19.1. 序列容器19.1.1. vector19.1.1.1. 底层实现和特点19.1.1.2. 常用函数19.1.1.3. emplace_back() vs push_back() 19.1.2. array19.1.2.1. 底层实现和特点19.1.2.2. 常用函数 19.1.3. deque19.1.3.1. 底层实现和特点19.1.3.2. 常用函数 19.1.4 list19.1.4.…...

Linux查看Oracle数据库的环境变量
Linux查看Oracle数据库的环境变量 在Linux上查看Oracle数据库的环境变量,通常涉及检查当前shell会话中已设置的环境变量。这些环境变量可能包括ORACLE_HOME、ORACLE_SID、PATH(可能包含Oracle二进制文件的路径)等。 以下是几种方法来查看这…...

pg数据库学习知识要点分析-1
知识要点1 对象标识OID 在PostgreSQL内部,所有的数据库对象都通过相应的对象标识符(object identifier,oid)进行管理,这些标识符是无符号的4字节整型。数据库对象与相应oid 之间的关系存储在对应的系统目录中…...