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类表示图书馆,包含了图书的集合和相关的操作方法。

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

我建立了一个资源分享群

我建立了一个资源分享群 在为寻找资源犯愁&#xff1f; 在为分享资源犯愁&#xff1f; 一起加入分享资源群&#xff08;是wx群哦&#xff09;吧&#xff01;你可以分享自己的资源帮助他人。你可以在群组里需求资源获取别人的帮助。发广告请绕行&#xff0c;会被拉黑哦 微信…

基于SpringBoot+Vue人力资源管理系统(前后端分离)

该项目完全免费 系统介绍 基于 SpringBootVue 实现的人力资源管理系统是为了提高企业人力资源管理水平而开发的。主要目标是通过对员工 及人力资源活动信息&#xff08;考勤、工资 ) 等的编制来提高企业效率。 系统一共分为五大菜单项&#xff0c;分别是首页、薪资管理、权…

Linux安装nginx(带http ssl)

nginx安装 nginx文件 以及gcc pcre zlib openssl 网盘下载 1.安装gcc yum -y install gcc gcc-c 2.安装pcre rpm -ivh pcre-8.32-17.el7.x86_64.rpm --force --nodeps rpm -ivh pcre-devel-8.32-17.el7.x86_64.rpm --force --nodeps 3.安装zlib tar -zxvf zlib-1.2.11.ta…

Bayes贝叶斯识别Spam Email垃圾邮件

目录 介绍&#xff1a; 一、Gaussian Naive Bayes(连续型变量) 1.1数据处理 1.2建模 1.3cross_val_score函数评估 1.4classification_report函数评估 1.5classification_report函数和cross_val_score函数的区别 二、 Multinomial Naive Bayes&#xff08;离散型变量&…

【算法设计与分析】分治-时间复杂度计算

目录 主定理 Master Theorem分治算法运行时间的递归表示主定理的简化形式 主定理的一般形式 递归树 Recursion Tree递归树的简单结论 主定理 Master Theorem 分治算法运行时间的递归表示 将原问题分解成 a 个子问题递归求解&#xff0c;每个子问题的规模是原问题的 1/b。同时子…

紫光展锐5G扬帆出海 | 欧洲积极拥抱更多5G选择

和我国一样&#xff0c;欧洲不少国家也在2019年进入5G商用元年&#xff1a;英国在2019年5月推出了5G商用服务&#xff0c;该国最大的移动运营商EE(Everything Everywhere)最先商用5G&#xff1b;德国在2019年年中推出5G商用服务&#xff0c;德国电信、沃达丰和 Telefonica是首批…

从0开始python学习-42.requsts统一请求封装

统一请求封装的目的&#xff1a; 1.去除重复的冗余的代码 2. 跨py文件实现通过一个sess来自动关联有cookie关联的接口。 3. 设置统一的公共参数&#xff0c;统一的文件处理&#xff0c;统一的异常处理&#xff0c;统一的日志监控&#xff0c;统一的用例校验等 封装前原本代…

手写视频裁剪框

<!-- 截取框 --><divv-show"isShow"class"crop-box":style"{width: cropWidth px,height: cropHeight px,left: cropX px,top: cropY px,}"ref"cropBox"mousedown"startInteraction"><!-- 内容在这里 --…

Kubernetes二进制部署 单节点

一、环境准备 k8s集群master1&#xff1a;192.168.229.90 kube-apiserver kube-controller-manager kube-scheduler etcd k8s集群node1: 192.168.229.80 kubelet kube-proxy docker flannel k8s集群node2: 192.168.229.70 kubelet kube-proxy docker flannel 至少2C2G 常见的k…

软件工程:数据流图相关知识和多实例分析

目录 一、数据流图相关知识 1. 基本介绍 2. 常用符号 3. 附加符号 二、数据流图实例分析 1. 活期存取款业务处理系统 2. 工资计算系统 3. 商业自动化系统 4. 学校人事管理系统 5. 教材征订系统 6. 高考录取统分子系统 7. 订货系统 8. 培训中心管理系统 9. 考务处…

【动态规划】【字符串】C++算法:140单词拆分

作者推荐 【动态规划】【字符串】扰乱字符串 本文涉及的基础知识点 动态规划 字符串 LeetCode140:单词拆分 II 给定一个字符串 s 和一个字符串字典 wordDict &#xff0c;在字符串 s 中增加空格来构建一个句子&#xff0c;使得句子中所有的单词都在词典中。以任意顺序 返回…

PyTorch|一次画一批图像

想想这样一个场景&#xff0c;我们训练了一个神经网络&#xff0c;输入一些信息&#xff0c;这个网络可以根据信息为我们生成相关图片。 这些图片并不是一张&#xff0c;而是多张&#xff0c;我们想把这些图片一次全部显示出来&#xff0c;而不是一张一张的显示&#xff08;这…

【JAVA】异常体系

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a; JAVA ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 Exception&#xff08;异常&#xff09;: Error: 结语 我的其他博客 前言 在Java编程中&#xff0c;异常处理是一个至关…

什么?谁?w (who what)

文章目录 什么&#xff1f;谁&#xff1f;w (who & what)默认的显示不显示标题行简洁模式显示更多信息 什么&#xff1f;谁&#xff1f;w (who & what) w可以认为是加强版的who&#xff0c;果然越简洁越强大&#xff0c;就比如less比more是功能更多的。 w不仅可以显示…

leetcode:2451. 差值数组不同的字符串(python3解法)

难度&#xff1a;简单 给你一个字符串数组 words &#xff0c;每一个字符串长度都相同&#xff0c;令所有字符串的长度都为 n 。 每个字符串 words[i] 可以被转化为一个长度为 n - 1 的 差值整数数组 difference[i] &#xff0c;其中对于 0 < j < n - 2 有 difference[i]…

element-ui table height 属性导致界面卡死

问题: 项目上&#xff0c;有个点击按钮弹出抽屉的交互, 此时界面卡死 原因分析: 一些场景下(父组件使用动态单位/弹窗、抽屉中使用), element-ui 的 table 会循环计算高度值, 导致界面卡死 github 上的一些 issues 和解决方案: Issues ElemeFE/element GitHub 官方讲是升…

LLM之RAG实战(十三)| 利用MongoDB矢量搜索实现RAG高级检索

想象一下&#xff0c;你是一名侦探&#xff0c;身处庞大的信息世界&#xff0c;试图在堆积如山的数据中找到隐藏的一条重要线索&#xff0c;这就是检索增强生成&#xff08;RAG&#xff09;发挥作用的地方&#xff0c;它就像你在人工智能和语言模型世界中的可靠助手。但即使是最…

实战演练 | Navicat 中编辑器设置的配置

Navicat 是一款功能强大的数据库管理工具&#xff0c;为开发人员和数据库管理员提供稳健的环境。其中&#xff0c;一个重要功能是 SQL 编辑器&#xff0c;用户可以在 SQL 编辑器中编写和执行 SQL 查询。Navicat 的编辑器设置可让用户自定义编辑器环境&#xff0c;以满足特定的团…

MobaXterm SSH 免密登录配置

文章目录 1.简介2.SSH 免密登录配置第一步&#xff1a;点击 Session第二步&#xff1a;选择 SSH第三步&#xff1a;输入服务器地址与用户名第四步&#xff1a;设置会话名称第五步&#xff1a;点击 OK 并输入密码 3.密码管理4.小结参考文献 1.简介 MobaXterm 是一个功能强大的终…

如何科学地防范冬季流感

如何科学地防范冬季流感 加强对呼吸系统传染病预防的观念 在乘坐地铁、公交、火车、飞机等公共交通工具时&#xff0c;应科学佩戴口罩。要经常洗手&#xff0c;定期通风&#xff0c;咳嗽或打喷嚏时要用手捂住口鼻&#xff0c;不要随地吐痰。 羊大师建议积极接种含有XBB变异株…