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

news2024/12/22 17:38:21

 

目录

一、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.coloradmin.cn/o/1361507.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【SpringCloud】之远程消费(进阶使用)

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是君易--鑨&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的博客专栏《SpringCloud开发之远程消费》。&#x1f3af;&a…

Linux第12步_磁盘重新分区

解决“挂载后的U盘出现中文乱码”后&#xff0c;我们接着学习“磁盘重新分区”&#xff0c;熟悉fdisk命令。 1、删除磁盘的分区 输入“cd /回车”&#xff0c;进入根目录 输入“ls /dev/sd*回车”&#xff0c;显示dev以sd所有文件。 输入“sudo fdisk /dev/sdb1回车” 输入…

瑜亮之争有结果了,6GHz(6425-7125MHz)全部或部分频段划分用于IMT系统

文章目录 6GHz&#xff08;6425-7125MHz&#xff09;全部或部分频段划分用于IMT系统Wi-Fi 7 使用的频段Wi-Fi 7 与IMT使用的频段存在重叠频谱分配有讲究6GHz频段未来如何利用如何看待6GHz频段划入IMT关于Wi-Fi 7 与IMT关于Wi-Fi 7(IEEE 802.11be EHT)关于IMT(International Mob…

从零开始的OpenGL光栅化渲染器构建1

前言 参照Learnopengl&#xff0c;我开始回顾OpenGL中的内容&#xff0c;最终目标是构建一个玩具级的光栅化渲染器&#xff0c;最好还能和之前做的光线追踪渲染器相结合&#xff0c;希望能够有所收获吧~ 包管理 之前我用CMake配置过OpenGL的环境&#xff0c;这样做出来的项目…

Vue3 + Vite + TypeScript + Element-Plus:从零到一构建企业级后台管理系统(前后端开源)

vue3-element-admin 是基于 vue-element-admin 升级的 Vue3 Element Plus 版本的后台管理前端解决方案&#xff0c;技术栈为 Vue3 Vite4 TypeScript Element Plus Pinia Vue Router 等当前主流框架。 相较于其他管理前端框架&#xff0c;vue3-element-admin 的优势在于一…

Python 面向对象之多态和鸭子类型

Python 面向对象之多态和鸭子类型 【一】多态 【1】概念 多态是面向对象的三大特征之一多态&#xff1a;允许不同的对象对同一操作做出不同的反应多态可以提高代码的灵活性&#xff0c;可扩展性&#xff0c;简化代码逻辑 【2】代码解释 在植物大战僵尸中&#xff0c;有寒冰…

vite4项目中,vant兼容750适配

一般非vite项目&#xff0c;使用postcss-px-to-viewport。在设计稿为750时候&#xff0c;可使用以下配置兼容vant。 在vite4项目中&#xff0c;以上配置不行。需要调整下&#xff0c;使用postcss-px-to-viewport-8-plugin&#xff0c;并修改viewportWidth&#xff0c;具体如下…

2 @RequestMapping 注解

1. RequestMapping 概念 SpringMVC 使用RequestMapping 注解为控制器指定可以处理哪些 URL 请求在控制器的类定义及方法定义处都可标注 RequestMapping 标记在类上&#xff1a;提供初步的请求映射信息。相对于 WEB 应用的根目录标记在方法上&#xff1a;提供进一步的细分映射信…

大创项目推荐 深度学习图像风格迁移 - opencv python

文章目录 0 前言1 VGG网络2 风格迁移3 内容损失4 风格损失5 主代码实现6 迁移模型实现7 效果展示8 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习图像风格迁移 - opencv python 该项目较为新颖&#xff0c;适合作为竞赛课题…

遇见狂神说 Spring学习笔记(完整笔记+代码)

简介 Spring是一个开源的免费的框架&#xff08;容器&#xff09;Spring是一个轻量级的、非入侵式的框架控制反转(IOC&#xff09;&#xff0c;面向切面编程 (AOP)支持事务的处理&#xff0c;支持对框架进行整合 Spring就是一个轻量级的控制反转&#xff08;IOC&#xff09;和…

视频智能分析支持摄像头异常位移检测,监测摄像机异常位移变化,保障监控状态

我们经常在生产场景中会遇到摄像头经过风吹日晒&#xff0c;或者异常的触碰&#xff0c;导致了角度或者位置的变化&#xff0c;这种情况下&#xff0c;如果不及时做出调整&#xff0c;会导致原本的监控条件被破坏&#xff0c;发生事件需要追溯的时候&#xff0c;查不到对应位置…

01-线程池项目背景:C++的数据库操作

从0开始学习C与数据库的联动 1.原始方式-使用MySQL Connector/C 提供的API查询 1.1 数据库预操作 我的本地电脑上有mysql数据库&#xff0c;里面预先创建了一个database名叫chat&#xff0c;用户名root&#xff0c;密码password。 1.2 Visual Studio预操作 在Windows上使用…

Linux与C/C++服务器开发:深入探索网络编程与实用技术(文末送书)

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; 书籍推荐 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1;前言一. 构建高性能Linux C/C服务器1.1 优化服务器性能1.2 处理并发和并行性1.3 高效管理内存1…

dnSpy调试工具二次开发1-新增菜单

测试环境&#xff1a; window 10 visual studio 2019 版本号&#xff1a;16.11.15 .net framework 4.8 开发者工具包 下载 .NET Framework 4.8 | 免费官方下载 .net 5开发者工具包 下载 .NET 5.0 (Linux、macOS 和 Windows) 利用git拉取代码(源码地址&#xff1a;Gi…

TypeError: loaderUtils.getOptions is not a function

webpack 版本&#xff1a;^5.89.0 但是直接 pnpm add loader-utils 安装的版本比较新&#xff0c;会报错&#xff1a;TypeError: loaderUtils.getOptions is not a function。 解决方案&#xff1a;将低 loader-utils 版本&#xff0c;我这里使用 ^2.0.0 就不会再报这个错误了 …

Pandas DataFrame中将True/False映射到1/0

在本文中&#xff0c;我们将看到如何在Pandas DataFrame中将True/False映射到1/0。True/False到1/0的转换在执行计算时至关重要&#xff0c;并且可以轻松分析数据。 1. replace方法 在这个例子中&#xff0c;我们使用Pandas replace()方法将True/False映射到1/0。在这里&…

十大性能测试工具

这篇关于“性能测试工具”的文章将按以下顺序让您了解不同的软件测试工具&#xff1a; 什么是性能测试&#xff1f; 为什么我们需要性能测试&#xff1f; 性能测试的优势 性能测试的类型 十大性能测试工具 什么是性能测试&#xff1f; 性能测试是一种软件测试&#xff0c;可确…

25考研经验贴之准备篇三

Hello各位小伙伴又见面了&#xff0c;今天要给大家分享一些大家在备考中可以用到的软件。 另外前两次分享的一些择校什么的也不够全面&#xff0c;今天又为大家找到了一个全面的考研常识讲解视频&#xff0c;有需要的可以关注公众号&#xff0c;在后台回复&#xff1a;考研常识…

Python自动点击器

一、如何制作一个Python自动点击器&#xff1f; 当用户单击开始键时&#xff0c;代码将从键盘获取输入&#xff0c;并在用户单击退出键时终止自动点击器&#xff0c;自动点击器开始单击指针放置在屏幕上的任何位置。我们将在这里使用pynput模块。 二、什么是自动点击器&#…

Traffic Flow Prediction via Spatial Temporal Graph NeuralNetwork

KEYWORDS Traffic Prediction, Graph Neural Networks, Spatial Temporal Model, Dynamic, Recurrent Neural Network, Transformer This paper is published under the Creative Commons Attribution 4.0 International (CC-BY 4.0) license ABSTRACT 交通流分析、预测和管理…