C++语言学习(五)—— 类与对象(一)

目录

一、类类型的定义

二、类成员的访问控制

2.1 什么是"类内"和"类外"

2.2 对于访问控制属性的说明

三、类类型的使用

3.1 进行抽象

3.2 声明类

3.3 实现类

3.4 使用类

四、构造函数的引入

五、析构函数的引入

六、重载构造函数的引入

6.1 函数重载

6.2 默认参数

七、复制构造函数的引入


一、类类型的定义

类类型的定义是指在面向对象编程中,用来描述某一类对象共同特征和行为的模板或蓝图。类是实例化对象的抽象概念,它定义了对象的属性和行为。以下是对类类型定义的详细概述:

  1. 类的名称:每个类都有一个唯一的名称,用于标识和区分不同的类。类的名称通常使用大驼峰命名法,以便清晰地表达类的含义和作用。

  2. 属性:类的属性是指存储在类中的数据。属性可以是基本数据类型(如整数、浮点数、布尔值等),也可以是其他类的对象。属性用于描述对象的特征。例如,一个人类的属性可以包括姓名、年龄、性别等。

  3. 方法:类的方法是指在类中定义的函数。方法用于实现对象的行为和操作。方法可以访问和操作类的属性,也可以与其他对象进行交互。例如,一个人类的方法可以包括吃饭、睡觉、工作等。

  4. 访问修饰符:类的访问修饰符用于控制类的可见性和访问权限。常见的访问修饰符publicprivateprotectedpublic修饰符表示类对外公开,可以被其他类访问;private修饰符表示类只能在自身内部访问;protected修饰符表示类可以被自身和子类访问。

  5. 构造函数:类的构造函数是特殊的方法,用于创建类的对象。构造函数在对象实例化时被自动调用,用于初始化对象的属性和执行其他必要的操作。一个类可以有多个构造函数,以支持不同的对象创建方式。

综上所述,类类型的定义包括类的名称、属性的定义和方法的定义,以及类的访问修饰符和构造函数。类类型用于描述对象的属性和行为,并提供了一种创建具体对象的模板或蓝图。类类型是面向对象编程的核心概念之一。

二、类成员的访问控制

类成员的访问控制是指在类中定义的属性和方法可以被外部代码访问的程度。

2.1 什么是"类内"和"类外"

在面向对象编程中,"类内"和"类外"是指在类定义内部和外部的概念。

  1. 类内:指的是在类的定义内部,也就是在类的大括号 { } 内部的代码块。在类内部可以定义类的成员(属性和方法),通过关键字 public、private、protected 或默认的包私有访问来控制成员的访问级别。类内的代码可以直接访问类的私有成员和受保护成员。

  2. 类外:指的是在类的定义外部,也就是不在类的大括号 { } 内部的代码块。类外的代码无法直接访问类的私有成员,只能通过类的公共接口来访问类的公共成员。类外的代码可以通过创建类的对象来使用类的公共成员。

类内部的代码可以直接访问类的所有成员,而类外部的代码只能通过类的对象来访问类的公共成员。

2.2 对于访问控制属性的说明

访问控制属性是用来控制类的成员(属性和方法)在类内和类外的可见性和访问性。在面向对象编程中,常见的访问控制属性有以下几种:

  1. Public(公共):被标记为public的成员可以在类内外部的任何地方访问。它们是类的公共接口,可以被其他类的对象直接访问和使用。

  2. Private(私有):被标记为private的成员只能在类的定义内部访问。私有成员对类的外部是隐藏的,其他类的对象无法直接访问私有成员。私有成员一般用于实现类的内部逻辑和数据封装。

  3. Protected(受保护):被标记为protected的成员可以在类内部和子类中访问,但对于类的外部是不可见的。受保护成员主要用于实现类的继承和派生,子类可以通过继承和重写来访问和修改受保护成员。

  4. 默认(包私有):如果在成员前不加任何访问控制属性修饰符,那么它的访问级别为默认的包私有访问。默认访问级别限制了成员的访问范围在同一个包内,对于其他包内的类是不可见的。

通过合理使用这些访问控制级别,可以实现对类成员的封装和保护。封装是面向对象编程的重要概念之一,通过限制对类成员的直接访问,可以提高代码的安全性、可维护性和可复用性。

三、类类型的使用

类类型的使用是指在程序中使用已定义的类。

下面是一个简单的示例代码,演示了如何使用已定义的类:

#include <iostream>

// 定义一个类
class MyClass {
private:
  int myPrivateVar; // 私有成员变量

public:
  int myPublicVar;  // 公有成员变量

  // 构造函数
  MyClass(int privateVar, int publicVar) {
    myPrivateVar = privateVar;
    myPublicVar = publicVar;
  }

  // 成员方法
  void display() {
    std::cout << "Private variable: " << myPrivateVar << std::endl;
    std::cout << "Public variable: " << myPublicVar << std::endl;
  }
};

int main() {
  // 创建对象并初始化
  MyClass obj(10, 20);

  // 调用对象的方法和访问对象的属性
  obj.display();
  std::cout << "Public variable value: " << obj.myPublicVar << std::endl;

  return 0;
}

在上述代码中,首先定义了一个名为MyClass的类,包含一个私有成员变量myPrivateVar和一个公有成员变量myPublicVar,以及一个成员方法display()。在main()函数中,通过创建一个MyClass对象obj并传入初始化参数10 和20 来使用该类。然后,通过调用对象的display()方法和访问对象的myPublicVar属性,对对象进行操作和访问。最后,将对象的公有变量值打印输出。

3.1 进行抽象

抽象是指隐藏实现细节,只暴露必要的接口和属性,分为数据抽象行为抽象

  1. 数据抽象:通过将复杂的数据结构和数据类型抽象为简单的数据类型,只暴露必要的接口来操作和访问数据。可以使用类的成员变量来实现,将其声明为private,只能通过公共接口访问和操作。数据的具体实现细节被隐藏,只能通过定义的接口来操作数据。

  2. 行为抽象:将对象的具体行为和实现细节抽象为类的成员方法和接口,隐藏实现细节,只暴露必要的方法接口。通过定义类的成员方法和接口,将对象的行为抽象为可调用的函数,外部调用者只需知道如何调用方法,无需关心具体实现细节。

通过数据抽象和行为抽象,实现代码的模块化、可重用和易理解。同时提供更好的安全性、封装性,使类的实现细节对外部透明,只需关注功能和接口。

3.2 声明类

声明类的语法如下:

#include <iostream>

class MyClass {
public:
    int getValue(); // 成员函数

private:
    int value; // 私有成员变量
};

在这个例子中,我们声明了一个名为MyClass的类,在类中一个成员函数getValue。私有成员变量value只能通过公有成员函数访问。

3.3 实现类

int MyClass::getValue() {
    return value;
}

我们接着上述示例代码,在类的外部实现MyClass的成员函数。

 .cpp文件中实现类的成员函数要在类的外部进行,由于这些函数不是类的一部分,所以需要使用::运算符来标识其所属的类。

3.4 使用类

int main() {
    // 创建对象
    MyClass obj1;

    // 调用成员函数
    std::cout << "Value of obj1: " << obj1.getValue() << std::endl;

    return 0;
}

在主函数中,我们创建了一个MyClass对象并调用了它们的成员函数。

四、构造函数的引入

构造函数是一种特殊的成员函数,用于在创建对象时初始化对象的数据成员。在C++中,构造函数的名称与类名相同,并且没有返回类型(甚至没有void)。

构造函数可以具有参数,用于接收创建对象时传递的初始化值。构造函数还可以重载,允许多个不同的构造函数用于不同的初始化方式。构造函数还可以设置默认参数值,以便在创建对象时可以省略参数。

下面是一个示例,在类中引入构造函数:

#include <iostream>

class MyClass {
public:
    // 默认构造函数
    MyClass();

    // 带参数的构造函数
    MyClass(int val);

    // 成员函数声明
    void setValue(int val);
    int getValue();

private:
    // 私有成员变量
    int value;
};

// 默认构造函数的定义
MyClass::MyClass() {
    value = 0;
}

// 带参数的构造函数的定义
MyClass::MyClass(int val) {
    value = val;
}

// 成员函数定义
void MyClass::setValue(int val) {
    value = val;
}

int MyClass::getValue() {
    return value;
}

int main() {
    // 使用默认构造函数创建对象
    MyClass obj1;
    std::cout << "Default Value: " << obj1.getValue() << std::endl;

    // 使用带参数的构造函数创建对象
    MyClass obj2(10);
    std::cout << "Value: " << obj2.getValue() << std::endl;

    return 0;
}

在这个例子中,我们添加了一个默认构造函数和一个带参数的构造函数。默认构造函数没有参数,会将value初始化为0。带参数的构造函数接受一个整数参数,并将其赋值给value。在主函数中,我们分别使用默认构造函数和带参数的构造函数来创建对象,并输出其值。

构造函数可以在对象创建时自动调用,以确保对象正确地初始化。如果没有明确定义构造函数,C++编译器将提供一个默认的无参构造函数,该函数将执行默认的初始化操作。

五、析构函数的引入

析构函数是一种特殊的成员函数,用于在对象销毁时清理对象的资源。它的名称与类名相同,但前面加上了一个波浪符(~)。

析构函数没有参数,也没有返回类型(甚至没有void)。它被自动调用,当对象超出其作用域、被显式删除或程序结束时。

在C++中,析构函数的作用是释放对象在其生命周期内所分配的资源,例如堆内存、打开的文件、网络连接等。我们可以在析构函数中编写清理资源的代码。

下面是一个示例,在类中引入析构函数:

#include <iostream>

class MyClass {
public:
    // 默认构造函数
    MyClass();

    // 析构函数
    ~MyClass();

    // 成员函数声明
    void setValue(int val);
    int getValue();

private:
    // 私有成员变量
    int *ptr;
};

// 默认构造函数的定义
MyClass::MyClass() {
    // 在构造函数中分配内存
    ptr = new int;
    *ptr = 0;
}

// 析构函数的定义
MyClass::~MyClass() {
    // 在析构函数中释放内存
    delete ptr;
}

// 成员函数定义
void MyClass::setValue(int val) {
    *ptr = val;
}

int MyClass::getValue() {
    return *ptr;
}

int main() {
    MyClass obj;
    obj.setValue(10);
    std::cout << "Value: " << obj.getValue() << std::endl;

    return 0;
}

在这个例子中,我们在构造函数中使用new运算符为 ptr成员变量分配了一块动态内存,并将其初始化为0。在析构函数中,我们使用delete运算符释放了这块内存。

在主函数中,我们创建了一个MyClass对象obj,设置了其值,并输出该值。当obj超出其作用域时,即主函数结束时,析构函数会自动被调用,释放 ptr指向的内存。

析构函数的主要作用是确保资源的正确释放,以避免内存泄漏或资源浪费。

六、重载构造函数的引入

重载构造函数是指在同一个类中定义多个具有不同参数列表的构造函数。通过重载构造函数,我们可以根据不同的需求来创建对象,提供更灵活的对象初始化方式。

在C++中,我们可以通过两种方式来重载构造函数:函数重载和默认参数。

6.1 函数重载

函数重载: 函数重载允许在同一个类中定义多个具有不同参数列表的构造函数,它们的名称相同但参数个数、类型或顺序不同。

下面是一个示例,演示了如何使用函数重载来实现多个构造函数:

#include <iostream>

class MyClass {
public:
    // 无参数的构造函数
    MyClass();

    // 带一个参数的构造函数
    MyClass(int val);

    // 带两个参数的构造函数
    MyClass(int val1, int val2);

    // 成员函数声明
    void setValue(int val);
    int getValue();

private:
    // 私有成员变量
    int value;
};

// 无参数的构造函数的定义
MyClass::MyClass() {
    value = 0;
}

// 带一个参数的构造函数的定义
MyClass::MyClass(int val) {
    value = val;
}

// 带两个参数的构造函数的定义
MyClass::MyClass(int val1, int val2) {
    value = val1 + val2;
}

// 成员函数定义
void MyClass::setValue(int val) {
    value = val;
}

int MyClass::getValue() {
    return value;
}

int main() {
    MyClass obj1; // 调用无参数的构造函数,默认初始化为0
    std::cout << "Value: " << obj1.getValue() << std::endl;

    MyClass obj2(10); // 调用带一个参数的构造函数,初始化为10
    std::cout << "Value: " << obj2.getValue() << std::endl;

    MyClass obj3(5, 7); // 调用带两个参数的构造函数,初始化为12
    std::cout << "Value: " << obj3.getValue() << std::endl;

    return 0;
}

在这个例子中,我们定义了三个不同的构造函数,分别是无参数的构造函数、带一个参数的构造函数和带两个参数的构造函数。通过不同的构造函数,我们可以根据不同的情况来创建对象。

6.2 默认参数

默认参数: 默认参数允许在构造函数中为某些参数提供默认值,这样在创建对象时可以省略对应的参数。

下面是一个示例,演示了如何使用默认参数来实现构造函数的重载:

#include <iostream>

class MyClass {
public:
    // 带一个参数的构造函数,默认值为0
    MyClass(int val = 0);

    // 成员函数声明
    void setValue(int val);
    int getValue();

private:
    // 私有成员变量
    int value;
};

// 带一个参数的构造函数的定义
MyClass::MyClass(int val) {
    value = val;
}

// 成员函数定义
void MyClass::setValue(int val) {
    value = val;
}

int MyClass::getValue() {
    return value;
}

int main() {
    MyClass obj1; // 调用带默认参数的构造函数,初始化为0
    std::cout << "Value: " << obj1.getValue() << std::endl;

    MyClass obj2(10); // 调用带一个参数的构造函数,初始化为10
    std::cout << "Value: " << obj2.getValue() << std::endl;

    return 0;
}

在这个例子中,我们在构造函数的参数列表中为参数val提供了默认值0。当创建对象时,如果没有显式地指定参数值,就会使用默认值进行初始化。

七、复制构造函数的引入

复制构造函数是一种特殊的构造函数,用于创建一个对象,该对象的内容和另一个同类型对象完全相同。复制构造函数通常是通过将另一个对象的成员变量的值复制到新对象中来实现的。

在C++中,默认情况下,编译器会为我们自动生成一个默认的复制构造函数。然而,如果我们需要对对象进行深拷贝(即复制对象及其动态分配的资源),或者需要自定义复制构造函数的行为,就需要手动定义复制构造函数。

下面是一个示例,演示了如何手动定义和使用复制构造函数:

#include <iostream>

class MyClass {
public:
    // 构造函数
    MyClass(int val);

    // 复制构造函数
    MyClass(const MyClass& other);

    // 成员函数声明
    void setValue(int val);
    int getValue();

private:
    // 私有成员变量
    int value;
};

// 构造函数的定义
MyClass::MyClass(int val) {
    value = val;
}

// 复制构造函数的定义
MyClass::MyClass(const MyClass& other) {
    value = other.value;
}

// 成员函数定义
void MyClass::setValue(int val) {
    value = val;
}

int MyClass::getValue() {
    return value;
}

int main() {
    MyClass obj1(10); // 创建一个对象并初始化为10

    MyClass obj2(obj1); // 使用复制构造函数创建一个新对象,内容和obj1相同

    std::cout << "Value of obj2: " << obj2.getValue() << std::endl;

    return 0;
}

在这个例子中,我们手动定义了一个复制构造函数MyClass::MyClass(const MyClass& other),它接受一个同类型的对象作为参数。在复制构造函数中,我们将参数对象的成员变量值复制到新对象中。

main()函数中,我们首先创建了一个对象obj1并初始化为10。然后,通过使用复制构造函数,我们创建了一个新对象obj2,它的值和obj1完全相同。

使用复制构造函数可以方便地创建对象的副本,而无需手动逐个复制成员变量的值。

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

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

相关文章

权限维持--windows

隐藏文件 ①文件属性隐藏 如何排查&#xff1a; 使用dir命令无法看到有特殊属性的文件需使用/a ②真隐藏 相当于给原本的文件增加系统文件属性、存档文件属性、只读文集属性、隐藏文件属性 如何排查&#xff1a; 取消受保护的操作系统文件 ③利用ADS隐藏 使用数据流 echo &…

我把PostgreSQL最核心的插件撸干净了!!!

作者&#xff1a;IT邦德 中国DBA联盟(ACDU)成员&#xff0c;10余年DBA工作经验&#xff0c; Oracle、PostgreSQL ACE CSDN博客专家及B站知名UP主&#xff0c;全网粉丝10万 擅长主流Oracle、MySQL、PG、高斯及Greenplum备份恢复&#xff0c; 安装迁移&#xff0c;性能优化、故障…

USB抓包工具:bushound安装及使用

一、环境搭建 下载busbound6.01安装包&#xff0c;安装完成&#xff0c;重启电脑。 二、工具配置 按照下图配置工具&#xff1a; 使能自动识别新设备 2. 设置抓取数据的容量 三、抓包 回到capture选项卡&#xff0c;在页面的右下角有个run的按钮&#xff0c;点击使能&…

Multi-Attention Transformer for Naturalistic Driving Action Recognition

标题&#xff1a;用于自然驾驶行为识别的多注意力Transformer 源文链接&#xff1a;https://openaccess.thecvf.com/content/CVPR2023W/AICity/papers/Dong_Multi-Attention_Transformer_for_Naturalistic_Driving_Action_Recognition_CVPRW_2023_paper.pdfhttps://openaccess…

快速幂算法6

eg: n10&#xff0c;10%20, 10/25, 5%21,4* 5/22, 2%20,4*256 0/20, 1024 递归算法 #include<iostream> using namespace std; long long quick_pow(int b,int e) {if(b0)return 0;if(e0)return 1;if(e%20){int tempquick_pow(b,e/2);return temp*temp;}if(e%2!0)…

MATLAB modem.qammod和randint函数

实在是受不了MATLAB改函数了 试图找到如何修改代码&#xff0c;诶嘿&#xff0c;失败了&#xff0c;那我就自己写一下吧 randint函数 %% P pre-MMSE clear all;clc % 参数设置 N_frame 100; %帧数 N_packet 1000; % 分组数 b 2; % 每符号比特数 M 2 ^ b; % 调制阶数 mod…

Flutter笔记:Widgets Easier组件库-使用隐私守卫

Flutter笔记 Widgets Easier组件库&#xff1a;使用隐私守卫 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https:…

local dimming(局部调光)介绍

文章目录 1. 什么是local dimming2. 工作原理3. 类型4. 优点5. 缺点和局限7. 技术发展趋势 1. 什么是local dimming local dimming&#xff08;局部调光&#xff09;是电视和显示器中用于提升画面对比度和画质的背光技术。其基本原理是将背光源&#xff08;通常是LED&#xff…

【3dmax笔记】001:3dmax2020下载及安装教程

一、3dmax2020安装教程 1、双击运行exe文件&#xff0c;提取安装程序到指定文件夹&#xff1b; 2、提取完成&#xff0c;安装程序启动&#xff0c;点击安装 3、点击接受许可协议&#xff1b; 4、设置安装位置&#xff0c;点击安装&#xff1b; 5、等待产品安装&#xff1b; 6、…

C++:vector基础讲解

hello&#xff0c;各位小伙伴&#xff0c;本篇文章跟大家一起学习《C&#xff1a;vector基础讲解》&#xff0c;感谢大家对我上一篇的支持&#xff0c;如有什么问题&#xff0c;还请多多指教 &#xff01; 如果本篇文章对你有帮助&#xff0c;还请各位点点赞&#xff01;&#…

【C++】牛客——OR64 求和

✨题目链接&#xff1a; OR64 求和 ✨题目描述 输入两个整数 n 和 m&#xff0c;从数列1&#xff0c;2&#xff0c;3.......n 中随意取几个数,使其和等于 m ,要求将其中所有的可能组合列出来 ✨输入描述: 每个测试输入包含2个整数,n和m ✨输出描述: 按每个组合的字典序排列…

如何使用 CapSolver 扩展找到 Google reCAPTCHA 站点密钥?

网站安全性在当今至关重要&#xff0c;Google reCAPTCHA 作为防止垃圾邮件和滥用行为的前线防御系统起着关键作用。reCAPTCHA 站点密钥是确保网站交互由人类驱动的唯一标识符。了解如何找到这个密钥对于网站管理员和开发人员来说至关重要。 什么是 reCAPTCHA 站点密钥 reCAPT…

做抖音小店需要清楚的5个核心点!

大家好&#xff0c;我是喷火龙。 不管你是在做抖音小店&#xff0c;还是在做其他的电商平台&#xff0c;如果已经做了一段时间了&#xff0c;但还是没有拿到什么结果&#xff0c;我所指的结果不是什么大结果&#xff0c;而是连温饱都解决不了&#xff0c;甚至说还在亏钱。 有…

翻转列表-力扣

题目 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1]示例 2&#xff1a; 输入&#xff1a;head [1,2] 输出&#xff1a;[2,1]示例 3&#xff1a; …

鸿蒙开发配置官方地图

一共需要配置 p12 p7b cer csr 四个文件 p12文件配置 注意创建文件名必须是.p12 到AGC创建项目 AppGallery Connect 添加自己的项目名称 我没有开启 暂时不需要 看个人需求 下载刚创建的cer证书 回到我的项目中 点击刚创建的项目 点击这里 四个文件齐全了 "metadata&qu…

【数据结构】哈夫曼树和哈夫曼编码

一、哈夫曼树 1.1 哈夫曼树的概念 给定一个序列&#xff0c;将序列中的所有元素作为叶子节点构建一棵二叉树&#xff0c;并使这棵树的带权路径长度最小&#xff0c;那么我们就得到了一棵哈夫曼树&#xff08;又称最优二叉树&#xff09; 接下来是名词解释&#xff1a; 权&a…

吉林大学软件工程易错题

1.【单选题】软件工程方法是&#xff08; &#xff09;。 A、为开发软件提供技术上的解决方法 &#xff08;软件工程方法 &#xff09; B、为支持软件开发、维护、管理而研制的计算机程序系统&#xff08;软件工程工具&#xff09; …

爬虫实训案例:中国大学排名

近一个月左右的时间学习爬虫&#xff0c;在用所积累的知识爬取了《中国大学排名》这个网站&#xff0c;爬取的内容虽然只是可见的文本&#xff0c;但对于初学者来说是一个很好的练习。在爬取的过程中&#xff0c;通过请求数据、解析内容、提取文本、存储数据等几个重要的内容入…

springboot基于Web前端技术的java养老院管理系统_utbl7

3.普通用户模块包括&#xff1a;普通会员的注册、养老院客房查询、养老院留言查询、预约老人基本信息登记、选择房间、用户缴费的功能。 4.数据信息能够及时进行动态更新&#xff0c;增删&#xff0c;用户搜素方便&#xff0c;使用户可以直接浏览相关信息&#xff0c;要考虑便于…

Unity Render Streaming 云渲染 外网访问

初版&#xff1a; 日期&#xff1a;2024.5.20 前言&#xff1a;临时思路整理&#xff0c;后期会详细补充 环境&#xff1a; 1. 阿里云服务器 需要安装好nodejs 、npm 2. windows电脑&#xff0c;需安装好 nodejs 、npm 3.Unity 2021.3.15f1 4.Unity Render Streaming …