C++学习笔记——类作用域和抽象数据类型

 

目录

一、C++类作用域

类内作用域

类外作用域

二、类作用域案列详细的解释说明

三、抽象数据类型

四、总结

类作用域

抽象数据类型(ADT)

五、图书馆管理系统


一、C++类作用域

在C++中,类作用域是指类定义中声明的标识符(成员变量、成员函数、嵌套类等)所存在的范围。类作用域可以分为两个部分:类内作用域和类外作用域。

  1. 类内作用域

    • 在类定义的内部,成员变量和成员函数的声明和定义都处于类内作用域。
    • 在类内部,可以直接访问类中定义的其他成员,无需使用限定符。
    • 类内部的成员函数可以直接访问类的私有成员。
  2. 类外作用域

    • 在类定义的外部,对类成员的访问需要使用类名和作用域解析运算符(::)来限定。
    • 类外部可以定义成员函数的实现,实现时需要使用类名和作用域解析运算符来指明成员函数所属的类。
    • 类外部的函数可以访问公有成员,但不能直接访问私有成员。

下面是一个示例,展示了类内作用域和类外作用域的使用:

class MyClass {
public:int publicMember;   // 公有成员变量void memberFunction() {privateMember = 10;   // 在类内部可以直接访问私有成员变量}private:int privateMember;   // 私有成员变量
};void MyClass::memberFunction() {publicMember = 20;   // 在类外部的成员函数中,使用作用域解析运算符来访问公有成员变量privateMember = 30;  // 在类外部的成员函数中,使用作用域解析运算符来访问私有成员变量
}int main() {MyClass obj;obj.publicMember = 40;   // 在类外部,使用对象和作用域解析运算符来访问公有成员变量return 0;
}

在上述示例中,MyClass类包含一个公有成员变量publicMember和一个私有成员变量privateMember。memberFunction是一个成员函数,它在类内部和类外部都有定义。

在类内部的成员函数中,可以直接访问类的私有成员变量privateMember。在类外部的成员函数中,需要使用作用域解析运算符来访问类的成员变量。在main函数中,我们创建了一个MyClass对象obj,并使用对象和作用域解析运算符来访问公有成员变量publicMember。

通过类作用域的概念,我们可以在类定义中方便地组织和访问成员变量和成员函数,并控制它们的可访问性。

二、类作用域案列详细的解释说明

如何使用类和对象来实现一个学生信息管理系统。该系统可以添加学生信息、显示学生信息和计算学生平均分。

#include <iostream>
#include <string>
using namespace std;class Student {
private:string name;int age;float score;public:Student(string n, int a, float s) {name = n;age = a;score = s;}void displayInfo() {cout << "Name: " << name << endl;cout << "Age: " << age << endl;cout << "Score: " << score << endl;}float getScore() {return score;}
};class StudentManager {
private:Student* students;int size;public:StudentManager(int maxSize) {students = new Student[maxSize];size = 0;}~StudentManager() {delete[] students;}void addStudent(string name, int age, float score) {students[size] = Student(name, age, score);size++;}void displayAllStudents() {for (int i = 0; i < size; i++) {students[i].displayInfo();cout << endl;}}float calculateAverageScore() {float totalScore = 0;for (int i = 0; i < size; i++) {totalScore += students[i].getScore();}return totalScore / size;}
};int main() {StudentManager manager(5);manager.addStudent("Alice", 20, 85.5);manager.addStudent("Bob", 21, 78.2);manager.addStudent("Charlie", 19, 92.0);cout << "All Students:" << endl;manager.displayAllStudents();float averageScore = manager.calculateAverageScore();cout << "Average Score: " << averageScore << endl;return 0;
}

这个案例中,我们定义了两个类:Student和StudentManager。

  • Student类表示一个学生对象,包含了学生的姓名、年龄和成绩。它具有一个构造函数用于初始化学生对象,一个displayInfo函数用于显示学生信息,以及一个getScore函数用于获取学生的成绩。

  • StudentManager类表示一个学生信息管理器,用于添加学生,显示所有学生信息和计算学生平均分。它使用动态内存分配来创建一个可变大小的学生对象数组,并通过addStudent函数将新的学生对象添加到数组中。displayAllStudents函数用于遍历数组并显示每个学生的信息。calculateAverageScore函数用于计算所有学生的平均分。

在主函数main中,我们创建了一个StudentManager对象manager,并使用addStudent函数添加了三个学生信息。然后,我们使用displayAllStudents函数显示所有学生的信息,并使用calculateAverageScore函数计算学生的平均分,并将结果打印出来。

这个案例展示了如何使用类和对象来组织和管理学生信息。通过类和对象的封装特性,我们可以方便地对学生信息进行操作和处理。

三、抽象数据类型

抽象数据类型(Abstract Data Type,ADT)是一种数学模型,用于描述数据对象的逻辑特性和对其进行操作的运算集合。在编程语言中,ADT是一种通过封装数据和操作来定义数据类型的方式,它将数据的表示和操作与实现细节相分离。

ADT包含两个主要组成部分:

  1. 数据对象:数据对象是指具有相同性质和操作的元素的集合。它们可以是简单的数据类型(如整数、浮点数、字符等),也可以是复杂的数据结构(如数组、链表、树等)。

  2. 操作集合:操作集合定义了对数据对象进行的操作或行为。这些操作可以是创建、初始化、访问、修改、删除等。每个操作都有一个名称和一组参数,用于操作数据对象。

ADT的设计目标是将数据类型的实现细节隐藏起来,使用户只能通过操作集合来访问和操作数据对象,而无需关心具体的实现细节。这样可以提高代码的可读性、可维护性和可重用性。

举个例子,我们可以以栈(Stack)为例来说明ADT的概念:

class Stack {
private:int* elements;int top;int maxSize;public:Stack(int size) {elements = new int[size];top = -1;maxSize = size;}~Stack() {delete[] elements;}void push(int value) {if (top < maxSize - 1) {top++;elements[top] = value;}}int pop() {if (top >= 0) {int value = elements[top];top--;return value;}return -1;}bool isEmpty() {return top == -1;}
};

在这个例子中,我们定义了一个抽象数据类型Stack,它表示一个栈数据结构。栈是一种具有后进先出(LIFO)特性的数据结构,可以使用push操作将元素压入栈顶,使用pop操作从栈顶取出元素。

在Stack类中,我们使用一个动态分配的整型数组elements来存储栈中的元素,使用变量top来标记栈顶位置,使用变量maxSize来表示栈的最大容量。通过push函数向栈中压入元素,通过pop函数从栈中取出元素,通过isEmpty函数判断栈是否为空。

通过这个例子,我们可以看到,使用抽象数据类型可以将数据结构的实现细节隐藏起来,用户只需关心如何使用操作集合来操作数据对象,而无需关心底层的实现细节。这样可以提高代码的可读性和可维护性,同时也方便了代码的重用和扩展。

四、总结

总结一下类作用域和抽象数据类型的主要内容

  1. 类作用域

    • 类作用域是指在类定义中声明的变量、函数和类型的可见性范围。
    • 在类作用域内部,成员变量和成员函数可以直接访问,无需使用任何限定符。
    • 类作用域可以通过访问修饰符(public、private、protected)来控制成员的可访问性。
    • 类作用域内的成员可以被类的对象访问和操作。
  2. 抽象数据类型(ADT)

    • ADT是一种通过封装数据和操作来定义数据类型的方式,将数据的表示和操作与实现细节相分离。
    • ADT包含一个数据对象和一组操作集合,其中数据对象是具有相同性质和操作的元素的集合,操作集合定义了对数据对象进行的操作或行为。
    • ADT的设计目标是隐藏数据类型的实现细节,使用户只能通过操作集合来访问和操作数据对象,而无需关心具体的实现细节。
    • ADT可以提高代码的可读性、可维护性和可重用性,同时也帮助管理复杂的数据结构和操作。

类作用域和抽象数据类型是面向对象编程中的重要概念。类作用域帮助管理类内部的成员访问和可见性,而抽象数据类型则提供了一种将数据和操作封装在一起的方式,使用户能够以更高层次的抽象来处理数据对象。这些概念在软件开发中起到了重要的作用,可以提高代码的可维护性、可扩展性和可重用性。

五、图书馆管理系统

一个经典的案例是实现一个图书管理系统。这个系统可以用来管理图书馆的图书信息,包括图书的名称、作者、出版日期等信息,并提供借阅和归还图书的功能。

下面是一个简化版本的图书管理系统的示例:

#include <iostream>
#include <string>
#include <vector>class Book {
private:std::string title;std::string author;int publicationYear;bool borrowed;public:Book(const std::string& bookTitle, const std::string& bookAuthor, int year): title(bookTitle), author(bookAuthor), publicationYear(year), borrowed(false) {}std::string getTitle() const {return title;}std::string getAuthor() const {return author;}int getPublicationYear() const {return publicationYear;}bool isBorrowed() const {return borrowed;}void borrowBook() {if (!borrowed) {borrowed = true;std::cout << "Successfully borrowed the book: " << title << std::endl;} else {std::cout << "The book is already borrowed." << std::endl;}}void returnBook() {if (borrowed) {borrowed = false;std::cout << "Successfully returned the book: " << title << std::endl;} else {std::cout << "The book is not currently borrowed." << std::endl;}}
};class Library {
private:std::vector<Book> books;public:void addBook(const Book& book) {books.push_back(book);}void listBooks() const {for (const auto& book : books) {std::cout << "Title: " << book.getTitle() << ", Author: " << book.getAuthor()<< ", Publication Year: " << book.getPublicationYear()<< ", Borrowed: " << (book.isBorrowed() ? "Yes" : "No") << std::endl;}}void borrowBook(const std::string& title) {for (auto& book : books) {if (book.getTitle() == title) {book.borrowBook();return;}}std::cout << "The book '" << title << "' is not available in the library." << std::endl;}void returnBook(const std::string& title) {for (auto& book : books) {if (book.getTitle() == title) {book.returnBook();return;}}std::cout << "The book '" << title << "' is not available in the library." << std::endl;}
};int main() {Library library;Book book1("The Great Gatsby", "F. Scott Fitzgerald", 1925);Book book2("To Kill a Mockingbird", "Harper Lee", 1960);Book book3("1984", "George Orwell", 1949);library.addBook(book1);library.addBook(book2);library.addBook(book3);library.listBooks();library.borrowBook("To Kill a Mockingbird");library.borrowBook("The Great Gatsby");library.listBooks();library.returnBook("To Kill a Mockingbird");library.listBooks();return 0;
}

这个案例中,我们定义了两个类:Book和Library。Book类表示一本书,包含了书的相关信息和借阅状态。Library类表示图书馆,包含了图书的集合和相关的操作方法。

在主函数中,我们创建了几本书,并将它们添加到图书馆中。然后,我们展示了图书馆中的所有书籍,并进行了一些借阅和归还操作。

这个案例虽然简化了实际的图书管理系统,但是它演示了如何使用类来管理对象的数据和行为,并展示了类之间的交互。这个案例可以作为一个起点,可以根据需求进一步扩展和完善图书管理系统的功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/327726.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何使用UUP从windows更新服务器下载windows10原版镜像

UUP是指Windows 10中的一种更新技术&#xff0c;全称为Unified Update Platform。UUP的目标是提供更快、更高效的更新体验&#xff0c;它通过增量更新的方式来更新操作系统&#xff0c;只下载和安装实际变化的部分&#xff0c;而不是整个更新包。这样可以节省带宽和时间&#x…

时间序列预测 — LSTM实现多变量多步负荷预测(Tensorflow):多输入多输出

目录 1 数据处理 1.1 导入库文件 1.2 导入数据集 ​1.3 缺失值分析 2 构造训练数据 3 LSTM模型训练 4 LSTM模型预测 4.1 分量预测 4.2 可视化 1 数据处理 1.1 导入库文件 import time import datetime import pandas as pd import numpy as np import matplotlib.p…

华为面经总结

为了帮助大家更好的应对面试&#xff0c;我整理了往年华为校招面试的题目&#xff0c;供大家参考~ 面经1 技术一面 自我介绍说下项目中的难点volatile和synchronized的区别&#xff0c; 问的比较细大顶堆小顶堆怎么删除根节点CSRF攻击是什么&#xff0c;怎么预防线程通信方式…

C#不会循环响应的Action设计与实现

目录 一、简述二、测试代码三、测试的输出四、核心代码五、其它 一、简述 特点&#xff1a; 不光是能防止直接的死循环调用&#xff1b;还能防止间接的死循环调用&#xff1b;还支持对不同参数判定&#xff0c;不同参数的调用可以不当循环调用&#xff1b; 消息事件系统中必…

leetcode——杨辉三角

https://leetcode.cn/problems/pascals-triangle/ 杨辉三角&#xff1a; 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 核心思想&#xff1a;找出杨辉三角的规律&#xff0c;发…

PromptCast:基于提示学习的时序预测模型!

目前时序预测的SOTA模型大多基于Transformer架构&#xff0c;以数值序列为输入&#xff0c;如下图的上半部分所示&#xff0c;通过多重编码融合历史数据信息&#xff0c;预测未来一定窗口内的序列数值。 受到大语言模型提示工程技术的启发&#xff0c;文章提出了一种时序预测新…

FastDFS实战

目录 目标 版本 环境 官方文档 相关概念 安装FastDFS 启动FastDFS 关闭FastDFS 重启FastDFS 用命令测试上传文件 用命令测试下载文件 用命令测试删除文件 用HTTP的方式访问FastDFS中的文件 用HTTP的方式访问FastDFS中的文件整体流程 目标 在Linux服务器上搭建Fa…

二分查找算法(指定数值的左右边界)

之前一直以为二分查找有什么难的&#xff0c;不就是确定左右边界&#xff0c;然后while循环求mid&#xff0c;大于mid的找右半边&#xff0c;小于mid的找左半边。直到最后相同了就是最后查找的结果了. 后来等真正用到二分查找算法的时候&#xff0c;发现问题远没有这么简单&…

代码随想录算法训练营第二十天| 回溯 理论基础 77. 组合

理论基础 回溯是一种搜索的方式。回溯是递归的副产品&#xff0c;只要有递归就会有回溯&#xff0c;回溯函数也是递归函数&#xff0c;指的是一个函数。 回溯法并不是什么高效的算法。因为回溯的本质是穷举&#xff0c;穷举所有可能&#xff0c;然后选出我们想要的答案&#…

回顾基础--HTML篇

HTML语法规范 <html></html> 开始标签与结束标签 <br /> 单标签 包含关系 <head><title></title> </head>并列关系 <head></head> <body></body> 1、 标题标签 标题标签 【双标签】 <h1> ~ &…

Linux离线安装MySQL(rpm)

目录 下载安装包安装MySQL检测安装结果服务启停MySQL用户设置 下载安装包 下载地址&#xff1a;https://downloads.mysql.com/archives/community/ 下载全量包如&#xff1a;(mysql-8.1.0-1.el7.x86_64.rpm-bundle.tar) 解压&#xff1a;tar -xzvf mysql-8.1.0-1.el7.x86_64.…

18.标题统计

题目 import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);String str sc.nextLine();int res 0;for(int i0;i<str.length();i) {char c str.charAt(i);if(c! && c!\n) {res;}}System.o…