C++----析构函数,拷贝构造函数(6)

news2024/11/15 8:41:49

析构函数

概念

析构函数是一个特殊的函数,函数名和类名相同,但是要在前面加~,既没有参数,也没有返回值。析构函数在对象被销毁自动调用一次

如果类中没有析构函数,编译器会生成一个什么也不做的析构函数

如果类中有析构函数,编译器不再做该动作

如果类中有类类型成员,先析构自己,在析构成员(先构造的要后析构)

练习: 为mystring类实现析构函数和获取指定位置字符的成员函数

/*06-字符串类的拷贝构造函数*/
#include <iostream>
#include <cstring>

using namespace std;

class mystring{
public:
    //构造函数
    mystring(const char *s=NULL)
    {
        if(!s){//没有传参数
            this->len = 10;
            this->str = new char[this->len];
            memset(this->str,0,10);
        }
        else{
            this->len = strlen(s)+1;
            this->str = new char[this->len];
            strcpy(this->str,s);
        }
    }

    //拷贝构造函数
    mystring(const mystring &s)
    {
        this->len = s.len;
        this->str = new char[this->len];
        strcpy(this->str,s.str);
    }

    //析构函数
    ~mystring()
    {
        delete[] this->str;
    }

    //打印字符串
    void show()
    {
        cout<<this->str<<endl;
    }

    //获取空间大小
    size_t get_len()
    {
        return this->len;
    }

    //获取字符串长度
    size_t get_size()
    {
        return strlen(this->str);
    }

    //获取指定位置的字符
    char at(size_t n)
    {
        if(n>=this->len){//越界
            return -1;
        }

        return this->str[n];
    }

    //修改字符串内容 健壮性
    void modify_str(const char *s)
    {
        if(!s){//为空修改为长度为10的空串
            delete[] this->str;
            this->len = 10;
            this->str = new char[this->len];
            memset(this->str,0,10);
        }
        else{//非空
            if(this->len<strlen(s)+1){//空间不够
                //调整空间
                delete[] this->str;
                this->len = strlen(s)+1;
                this->str = new char[this->len];
            }
            strcpy(this->str,s);
        }
    }

private:
    char *str;//字符串内容首地址
    size_t len;//空间大小
};


int main()
{
    //mystring str1;
    mystring str1("welcome to GEC!");
    str1.show();

    mystring str2 = str1;
    str2.show();
    str1.modify_str("byebye");
    str1.show();
    str2.show();

    cout<<str1.get_size()<<endl;

    return 0;
}

拷贝构造函数

概念

拷贝构造函数是一个特殊的构造函数,使用一个已有对象去初始化一个新建对象时,调用拷贝构造函数。

//A是类类型
A a;//构造函数
A b = a;//拷贝构造函数
A c;
c = a;//不是拷贝构造

实现语法

class A{
public:
A(…){…}//构造函数
/拷贝构造/
A(const A &a){…}
};

拷贝构造函数调用的时机

使用已有的对象去初始化新对象

A a;
A b = a;//拷贝构造
把一个对象传递给本类型的形参
把一个对象作为函数的返回值(编译器会优化成传递构造)

什么情况需要重写拷贝构造函数

如果一个类没有拷贝构造函数,编译器会自动生成一个按逐字节拷贝的拷贝构造函数

如果希望自定义拷贝构造的过程可以重写拷贝构造函数,其实就是对象中存在独立的内存(资源)重写拷贝构造

默认的拷贝构造函数属于浅拷贝

为独立内存重新分配空间,并拷贝空间中的数据就叫深拷贝

拷贝构造是由一个旧对象初始的值去拷贝新对象的值

在这里插入图片描述

/*09-字符串类的静态函数*/
#include <iostream>
#include <cstring>

using namespace std;

class date {
public:


    date(int year = 2022, int month = 7, int day = 9) {
        this->year = year;
        this->month = month;
        this->day = day;
    }

    void show() {
        cout << "year  " << this->year << " month  " << this->month << " day " << day << endl;

    }

    date(const date &dt) {
        cout << "  date(const date &t)" << endl;
        this->year = dt.year;
        this->month = dt.month;
        this->day = dt.day;

    }

    ~date() {  //析构要跟类名相同
        cout << "~getdate" << endl;
    };

private:
    int year;
    int month;
    int day;
};


int main() {

    date dt1(2000, 11, 20);
    dt1.show();

    date dt2(0000, 0000, 00);
    dt2 = dt1;
    dt2.show();
    //析构函数会在函数结束后执行
    return 0;

}

练习:

为mystring类直线拷贝构造函数,并提供获取字符串长度(有效字符个数)的成员函数。

/*06-字符串类的拷贝构造函数*/
#include <iostream>
#include <cstring>

using namespace std;

class mystring{
public:
    //构造函数
    mystring(const char *s=NULL)
    {
        if(!s){//没有传参数
            this->len = 10;
            this->str = new char[this->len];
            memset(this->str,0,10);
        }
        else{
            this->len = strlen(s)+1;
            this->str = new char[this->len];
            strcpy(this->str,s);
        }
    }

    //拷贝构造函数
    mystring(const mystring &s)
    {
        this->len = s.len;
        this->str = new char[this->len];
        strcpy(this->str,s.str);
    }

    //析构函数
    ~mystring()
    {
        delete[] this->str;
    }

    //打印字符串
    void show()
    {
        cout<<this->str<<endl;
    }

    //获取空间大小
    size_t get_len()
    {
        return this->len;
    }

    //获取字符串长度
    size_t get_size()
    {
        return strlen(this->str);
    }

    //获取指定位置的字符
    char at(size_t n)
    {
        if(n>=this->len){//越界
            return -1;
        }

        return this->str[n];
    }

    //修改字符串内容 健壮性
    void modify_str(const char *s)
    {
        if(!s){//为空修改为长度为10的空串
            delete[] this->str;
            this->len = 10;
            this->str = new char[this->len];
            memset(this->str,0,10);
        }
        else{//非空
            if(this->len<strlen(s)+1){//空间不够
                //调整空间
                delete[] this->str;
                this->len = strlen(s)+1;
                this->str = new char[this->len];
            }
            strcpy(this->str,s);
        }
    }

private:
    char *str;//字符串内容首地址
    size_t len;//空间大小
};


int main()
{
    //mystring str1;
    mystring str1("welcome to GEC!");
    str1.show();

    mystring str2 = str1;
    str2.show();
    str1.modify_str("byebye");
    str1.show();
    str2.show();

    cout<<str1.get_size()<<endl;

    return 0;
}

类中的特殊成员

const对象和const成员

语法

class A{
public:
    A(int n=0,int m=0):num(n),num_1(m){}
    void show(){....}
    void show()const{....}//const成员函数

private:
    const int num;//const成员变量
    int num_1;            
};

A a;
const A b;//const对象

应用

1.const成员函数和同名的非const成员函数构成重载关系
非const对象优先调用非const函数,const对象只能调用const函数
2.const成员函数只能读取成员变量,不能修改成员变量
如果一定要修改,必须在声明该成员变量前加mutable修饰符
如果一个成员函数不会修改成员变量,就应该将其设计为const成员函数
3.const成员变量和const对象都不能修改

静态(static)成员

静态成员分为静态成员变量和静态成员函数,静态成员属于类,不属于某个对象。

静态成员变量

静态成员变量在成员变量声明前加static,必须初始化,而且应该在类外初始化,默认初始化为0,类类型的静态成员变量调用默认构造函数。

静态成员函数

静态成员变量在成员函数声明前加static,静态成员函数只能访问静态成员变量,不能访问普通成员变量。
语法:

class A{
public:
    static int num;//静态成员变量    
    static void show(){......}//静态成员函数
};

//类外初始化
int A::num = xxx;

//访问静态成员
类名::静态成员;

静态成员无需通过对象来访问,可以直接通过类名访问。实现的机制是静态成员存储在独立的内存中,不能在在静态成员函数中使用this指针。所有同类型的对象访问的是同一个静态成员。

练习:

为mystring类提供一个静态成员函数,该函数返回一个指定长度的存储字符串的空间(char *)。

/*07-const对象和const成员*/
#include <iostream>
#include <cstring>

using namespace std;

class mystring {

public:
    static char *getSpace(size_t t) {
        return new char[t];

    }

private:
    size_t len;
    char *s;

};

int main() {
    char *string1 = mystring::getSpace(10);
    strcpy(string1, "helloworld");
    cout << string1 << endl;
    cout << sizeof(string1) << endl; //8
    return 0;
}

友元

友元的作用就是让类外数据突破访问权限的限制,可以将 类/函数 声明为某个类的友元,友元类和友元函数可以访问类中的所有数据,不受访问权限的限制。

友元函数

友元函数是一个全局函数,在类内将函数声明为友元,这个全局函数就可以访问类中的所有数据,语法如下:

在类内部声明:
friend 函数声明;

友元类

有一个类A,在类A中将类B声明为友元,类B就可以访问类A中的所有数据,语法如下:

在类的内部声明:
    friend class 友元类名;

注意:友元不受访问权限的限制,可以访问类中的所有数据,破坏了类的封装属性,如非必要,不要使用。

作业:

实现以下类的构造函数(默认构造长度为10,值为0的数组),析构函数和拷贝构造函数

class MyArray{
public:

private:
    int *pdata;//数组首地址
    size_t len;//数组元素个数        
};

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

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

相关文章

磁盘调度算法(期末复习版)

文章目录 一. FCFS 调度(先来先服务)二.SSTF调度(最短寻道时间优先)三. SCAN 调度(电梯算法)四. C-SCAN 调度(循环扫描)五. LOOK 调度 一. FCFS 调度(先来先服务) 磁盘调度的最简单形式当然是先来先服务&#xff08;FCFS&#xff09;算法。虽然这种算法比较公平&#xff0c;但…

MySQL千亿级数据生产环境扩容

MySQL千亿级数据生产环境扩容 数据库平滑扩容1. 扩容方案剖析1.1 扩容问题1.2 停机方案1.3 停写方案1.4 日志方案1.5 双写方案&#xff08;中小型数据&#xff09;1.6 平滑2N方案&#xff08;大数据量&#xff09; 2. 平滑2N扩容方案实践2.1 实现应用服务级别的动态扩容2.1.1 M…

时间序列表征之SAX(Symbolic Aggregate approXimation)算法

前言 对于研究时间序列表征、时间序列分类&#xff0c;时间序列状态转换等方向&#xff0c;常用的简单粗暴的一个方法是SAX (Symbolic Aggregate approXimation), 由Jessica Lin等在2003年发表的论文中提出的&#xff0c;该论文的题目为《A Symbolic Representation of Time Se…

敏捷方法中测试人员的价值?

敏捷方法在软件开发中受到青睐&#xff0c;特别是在互联网应用服务系统的开发中&#xff0c;越来越多的公司采用敏捷方法&#xff0c;包括XP、Scrum、Lean、Crystal、FDD等。具体的敏捷方法在操作时有一些区别&#xff0c;但基本思想是一致的&#xff0c;如客户至上、拥抱变化、…

yolov8 源码解读 (part1: backbone, head)

yolov8 除了目标检测之外,还有实例分割功能, 这里解读检测和分割代码。 先上一张结构图,这个图里没有分割模块,后面会在代码里说明分割模块。 本篇解读红色框内的部分。 可以看到每个模块右边都有一个数字:0,1,… 这个数字是模块的顺序编号,按0,1,…,21的顺序进行,而…

澎湃新闻对话腾讯丁珂:从“治已病”到“治未病”,企业需快速构建“安全免疫力”

作者&#xff1a;澎湃新闻记者 周頔 随着数字化进程加快&#xff0c;企业数字化体系的边界在不断拓展&#xff0c;安全风险和挑战不断增加&#xff0c;传统被动防御的安全应对常显疲态&#xff0c;数字安全时代亟待建立全新的安全范式。 6月13日&#xff0c;腾讯安全联合IDC等…

华为某正式员工哀叹:自己被劝退了,同期入职的OD还好好的,正式员工还没外包稳定!...

在打工人心中&#xff0c;正式员工的含金量远远高于外包&#xff0c;但最近却有人爆料&#xff1a;华为正式员工还没外包稳定&#xff01; 一位硕士毕业、工作两年的华为正式员工说&#xff0c;自己被劝退了&#xff0c;但隔壁组同期入职的OD还好好的&#xff0c;正式员工竟然还…

Instant-NGP稿子

Instant-NGP是英伟达2022年发表的一篇论文&#xff0c;全称是使用哈希编码的多分辨率的即时神经图形原语 那这篇文章呢 这篇文章提出了一种对输入做哈希encoding的方式&#xff0c;来让很小的网络也能学到很高的质量。 这个图片是文中的一个图片&#xff0c;表现了可以在训练…

大数据Doris(四十六):Stream Load基本原理和语法介绍

文章目录 Stream Load基本原理和语法介绍 一、基本原理 二、语法与结果 1、语法 2、返回结果 Stream Load基本原理和语法介绍 Stream load 是一个同步的导入方式&#xff0c;用户通过发送 HTTP 协议发送请求将本地文件或数据流导入到 Doris 中。Stream load 同步执行导入…

简要介绍 | 图像聚类:概念、原理与方法

注1&#xff1a;本文系“简要介绍”系列之一&#xff0c;仅从概念上对图像聚类进行非常简要的介绍&#xff0c;不适合用于深入和详细的了解。 图像聚类&#xff1a;概念、原理与方法 Cluster Analysis | NVIDIA Developer 1. 背景介绍 图像聚类&#xff08;Image Clustering&a…

波浪理论与伦敦金价走势分析

艾略特波浪理论(Elliott Wave Theory)是一套能应用于伦敦金走势分析的理论&#xff0c;它认为市场的走势会不断重复一种模式&#xff0c;每一周期由5个上升浪和3个下跌浪组成。波浪理论将不同规模的趋势分成了九大类&#xff0c;最长的超大循环波(Grand supercycle) 是横跨200年…

Git版本管理实用指南

特别声明&#xff0c;本博文仅作个人日常使用Git参考之用。主要内容总结来源于&#xff1a;廖雪峰官网的Git教程&#x1f33b; &#x1f50e; 什么是Git Git是目前世界上最先进的分布式版本控制系统&#xff0c;是Linux的创建者用C开发的。GitHub网站2008上线&#xff0c;它为…

ELKB架构安装

文章目录 安装JAVA JDK安装ES手动安装Problem: 无法访问localhost:9200Problem: 用户名密码验证 docker安装ES文件夹内容 安装node.js安装grunt 安装kibanaLogstashBeat 安装JAVA JDK https://www.java.com/en/ 添加环境变量C:\Program Files\Java\jdk-11.0.1\bin Elasticse…

在线广告系统工程架构

一、广告系统概览 广告投放系统&#xff1a;供广告主使用&#xff0c;核心功能包括会员续费、广告库管理、设定推广条件、设置广告出价、查看投放效果等。广告运营后台&#xff1a;供平台的产品运营使用&#xff0c;核心功能包括广告位管理、广告策略管理、以及各种运营工具。广…

HarmonyOS学习路之开发篇—多媒体开发(相机开发 一)

HarmonyOS相机模块支持相机业务的开发&#xff0c;开发者可以通过已开放的接口实现相机硬件的访问、操作和新功能开发&#xff0c;最常见的操作如&#xff1a;预览、拍照、连拍和录像等。 基本概念 相机静态能力 用于描述相机的固有能力的一系列参数&#xff0c;比如朝向、支持…

华为OD机试之按单词下标区间翻转文章内容(Java源码)

文章目录 按单词下标区间翻转文章内容题目描述输入描述输出描述示例代码 按单词下标区间翻转文章内容 题目描述 给定一段英文文章片段&#xff0c;由若干单词组成&#xff0c;单词间以空格间隔&#xff0c;单词下标从0开始。 请翻转片段中指定区间的单词顺序并返回翻转后的内…

芯片工程师求职题目之设计基础篇(1)

1. 进制转换 会算数值在二进制、八进制、十进制以及十六进制之间的任意转换。 会算数值的正码、反码、补码、BCD码。 2. 什么是格雷码(Gray code)&#xff0c;它有什么优点。 在一组二进制编码中&#xff0c;若任意两个相邻的数值还有1位二进制数不同&#xff0c;则称这种编…

算法程序设计 之 最长公共子序列(4/8)

一、实验目的&#xff1a; 理解并掌握动态规划算法的基本思想和设计步骤。 实验内容若给定序列X{x1,x2,...,xm},Z{z1,z2,...,zk},若Z是X的子序列&#xff0c;当且仅当存在一个严格递增下标序列{i1,...,ik}&#xff0c;使得对于所有j1,2,...,k有&#xff1a;zjxij。例如&#x…

智能家居APP软件开发有何优势?

传统家居行业营销模式已经无法满足现代人多样化个性化的需求&#xff0c;也跟不上互联网时代的发展步伐了&#xff0c;很多传统家居行业都陷入了营销困境。通过智能家居APP软件开发&#xff0c;可以利用互联网改造传统模式&#xff0c;探索新的发展模式&#xff0c;可以说智能家…

Bootstrap 简介

文章目录 Bootstrap 简介什么是 Bootstrap&#xff1f;Bootstrap 包的内容Bootstrap 实例 Bootstrap 简介 什么是 Bootstrap&#xff1f; Bootstrap 是一个用于快速开发 Web 应用程序和网站的前端框架。Bootstrap 是基于 HTML、CSS、JAVASCRIPT 的。 历史 Bootstrap 是由 Twi…