Linux 学习记录42(C++篇)

这篇具有很好参考价值的文章主要介绍了Linux 学习记录42(C++篇)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Linux 学习记录42(C++篇)

Linux 学习记录42(C++篇)

一、class 类

1. 类中的this指针

类内默认提供给非静态成员函数的this指针,指针指向类对象本身,哪个对象调用成员函数,this就指向哪个对象

(1. this指针的格式

格式:类名* const this; //不能改变this的指向

(2. 使用this指针

1. 如果函数的形参和成员属性同名时,需要使用this指针解决
2. 拷贝赋值函数中,需要返回自身的引用,也需要使用this指针解决
class Rectangle
{
private://私有的成员属性/方法
    int a;
public://公有的成员属性/方法
    void set_a(int a)
    {
"在这里函数的参数a和类中的a变量名重复所以无法确定到底是那个变量,所以需要用到this指针"
        a = a;
    }

protected://受保护的成员属性/方法
};
============================修改后如下================================
class Rectangle
{
private://私有的成员属性/方法
    int a;
public://公有的成员属性/方法
    void set_a(int a)
    {
         this->a = a;
    }
protected://受保护的成员属性/方法
};

2. 类中特殊的成员函数

如果程序员不手动定义,系统会默认提供的函数,系统默认提供的是无参构造

1. 构造函数 (常用)
2. 析构函数 (常用)
3. 拷贝构造函数 (常用)
4. 拷贝赋值函数 (常用)
5. 取地址运算符重载函数
6. 常取地址运算符重载函数
7. C++11新增:移动构造函数
8. C++11新增:移动赋值函数

(1. 构造函数

使用情景:
1. 形参和成员属性同名
2. 类内有引用成员,必须使用初始化列表
3. 类内有const修饰的成员时,必须使用初始化列表
4. 类中包含其他类的的子对象时,其他类必须初始化时,需要使用初始化列表
>1 格式/定义

用于实例化类对象时,系统自动调用

功能:实例化类对象时,给类对象开辟空间和初始化
格式:类名(形参列表)
{
	函数体;
}
例:
class test
{
private://私有的成员属性/方法
    int a;
    string b;
    double c;
public://公有的成员属性/方法
    /*有参构造和无参构造构成函数重载*/
    test(int a,string b,double c)
    {   //有参构造
        this->a=a;
        this->b=b;
        this->c=c;
    }
    test()
    {
        //无参构造
    }
protected://受保护的成员属性/方法
};

int main()
{
    test p;
    test p1(1,"abc",1.23);
    return 0;
}
>2 调用构造函数的时机

构造函数一般是public权限的

  1. 在栈区

什么时候实例化对象,什么时候调用构造函数,系统默认调用

  1. 在堆区申请空间

什么时候用new申请空间,什么时候调用构造函数

>3 构造函数的初始化列表

构造函数提供了初始化列表的机制,在函数体外

格式: 类名(形参列表):成员属性1(参数1),成员属性2(参数2),成员属性3(参数3)...
{
	函数体
}
例:
class test
{
private://私有的成员属性/方法
    int a;
    string b;
    double c;
public://公有的成员属性/方法
    /*有参构造和无参构造构成函数重载*/
    test(int a,string b,double c):a(a),b(b),c(c)
    {   //有参构造
        /*函数体内的赋值
        this->a=a;
        this->b=b;
        this->c=c;*/
    }
protected://受保护的成员属性/方法
};

(2. 析构函数

>1 功能/格式

功能:在类对象消亡时回收类对象的空间

格式:
~类名()
{
	函数体
}
>2 析构函数的调用时机

先构造的后析构

  1. 在栈区:

系统在对象消亡时,主动调用

  1. 在堆区:

使用delete关键字,释放空间时,主动调用析构函数

>3 需要显性调用析构函数情况
1. 系统会默认析构函数,在对象消亡时,主动调用,释放对象的空间
2. 析构函数不允许函数重载
3. 当类中有指针成员(指向堆区申请的空间)时,
>4 定义和使用

析构函数不支持重载

class test
{
private://私有的成员属性/方法
    int a;
    int* p;
    string b;
    double c;
public://公有的成员属性/方法
    /*析构函数,会自动调用*/
    ~test()
    {
        /*释放指针指向的堆区空间地址*/
        delete p;
        p = nullptr;
    }
protected://受保护的成员属性/方法
};

int main()
{
    test* p = new test;
    delete p;
    return 0;
}

(3. 拷贝构造函数

使用已有类对象给新的类对象初始化时,会自动调用拷贝构造函数

>1 格式
类名(类名 &other)
{
	函数体;
}
>2 调用时机
1. 使用已有的类对象给新的类对象初始化的时候,主动调用拷贝构造函数
2. 类对象作为函数的形参,主动调用拷贝构造函数
3. 类对象作为函数的返回值,主动调用拷贝构造函数
>3 定义和使用
class test
{
private://私有的成员属性/方法
    int num;
    string str;
public://公有的成员属性/方法
    test()
    {//无参构造函数
    }
    test(test &other)
    {//拷贝构造函数
        num = other.num;
        str = other.str;
    }
protected://受保护的成员属性/方法
};

int main()
{
    test p1;//定义一个p1变量
    test p2 = p1;//将p1拷贝一份给p2
    return 0;
}
>4. 深/浅拷贝

如果类内有指针成员,涉及到深浅拷贝问题

  1. 浅拷贝

两个不同类对象的指针成员指向同一片空间,会造成一个类对象对其修改另一个类对象的值也会修改

  1. 深拷贝

两个不同类对象的指针成员指向不同的空间,一个类对象的修改不会影响另一个类对象的值。

(4. 拷贝赋值函数

使用一个类对象给另一个类对象赋值时使用的,适于运算符重载

>1 格式

运算符重载的函数名:operator=

类名 &(const 类名 &引用)
{
	函数体;
}
拷贝赋值函数会返回自身的引用
>2 定义
class test
{
private://私有的成员属性/方法
    int num;
    string str;
public://公有的成员属性/方法
    test()
    {
    }
    test &operator=(test &other)
    {
        num = other.num;
        str = other.str;
        return *this;//返回自身
    }
protected://受保护的成员属性/方法
};
>3. 深/浅拷贝

拷贝赋值函数依然需要考虑深浅的问题,但是不需要再申请空间
要保证指针成员指向的地址在堆区才能delete释放

using namespace std;

class test
{
private://私有的成员属性/方法
    int num;
    int* p;
    string str;
public://公有的成员属性/方法
    test()
    {
    }
    test(int a,int* b,string c):num(a),p(b),str(c)
    {
    }
    test &operator=(test &other)
    {
        cout << "拷贝赋值" <<endl;
        *p = *(other.p);//深拷贝
//        p = other.p;//浅拷贝
        num = other.num;
        str = other.str;
        return *this;//返回自身
    }
    void show(void)
    {
        cout << "p=" << p <<endl;
        cout << "num=" << *p <<endl;
    }
    ~test()
    {
        cout << "空间已释放" <<endl;
        delete p;
        p = nullptr;
    }
protected://受保护的成员属性/方法
};

int main()
{
    int num1 = 1;
    int num2 = 2;
    test buf1(num1,&num1,"buf1");
    test buf2(num2,&num2,"buf2");

    buf1.show();
    buf2.show();

    buf1 = buf2;
    cout << "--------" <<endl;

    buf1.show();
    buf2.show();

    return 0;
}

3. 匿名对象

匿名对象就是实例化对象时,没有实例名的对象,它的生命周期短,是一个临时值

(1.使用场景

使用场景:
1. 用作全局函数的临时传参
2. 使用临时对象给另一个类对象赋值
3. 临时使用成员方法
4. 类对象数组

(2. 定义

class test
{
private://私有的成员属性/方法
    int num;
    int* p;
    string str;
public://公有的成员属性/方法
    test(int a,int* b,string c):num(a),p(b),str(c)
    {
    }
protected://受保护的成员属性/方法
};

int main()
{
    int num1 = 1;
    test (num1,&num1,"buf1");//这里就实例化了一个匿名对象
    return 0; 
}

4. 类的大小

类的大小和结构体的大小是一致的,类中的函数在声明时也是不占用空间的
string类型 在64位占32个字节,32位占24字节(QT内)

string类型包含以下几个部分(QT中)
1. 指向字符数组的指针
2. 字符串的实际长度 size_t
3. 字符串能存储的最大长度
4. 系统能存储的最大长度

思维导图

Linux 学习记录42(C++篇)文章来源地址https://www.toymoban.com/news/detail-511262.html

练习

#include <iostream>
#include <iomanip>
#include <cstring>
#include <cstdio>

using namespace std;

class Person
{
private:
    int age;
    int *p;
public:
    //无参构造
    Person():p(new int(89))
    {
        age = 18;
    }
    //有参构造
    Person(int age,int num)
    {
        this->age = age;
        this->p=new int(num);
    }
    //拷贝构造函数
    Person(Person &other)
    {
        age = other.age;
        p = new int (*(other.p));//深拷贝
//        p = other.p;//浅拷贝
    }
    //拷贝赋值函数
    Person operator=(Person &other)
    {
        age = other.age;
        *p = *(other.p);//深拷贝
//        p = other.p;//浅拷贝
        return *this;
    }
    //析构函数
    ~Person()
    {
        delete p;
        p = nullptr;
    }
};

int main()
{

    return 0;
}




到了这里,关于Linux 学习记录42(C++篇)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • LeetCode-42. 接雨水【栈 数组 双指针 动态规划 单调栈】

    LeetCode-42. 接雨水【栈 数组 双指针 动态规划 单调栈】

    给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 示例 1: 输入:height = [0,1,0,2,1,0,1,3,2,1,2,1] 输出:6 解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。

    2024年02月04日
    浏览(10)
  • 某60区块链安全之未初始化的存储指针实战二学习记录

    某60区块链安全之未初始化的存储指针实战二学习记录

    学会使用python3的web3模块 学会分析以太坊智能合约未初始化的存储指针漏洞 找到合约漏洞进行分析并形成利用 Ubuntu18.04操作机 python3 在solidity语言中,像动态的数组、struct、mapping这样的复杂数据结构是不能直接在”栈”里面保存的,因为”栈”里只能保存单独的”字”,也就

    2024年02月05日
    浏览(14)
  • 某60区块链安全之未初始化的存储指针实战一学习记录

    某60区块链安全之未初始化的存储指针实战一学习记录

    学会使用python3的web3模块 学会分析以太坊智能合约未初始化的存储指针漏洞 找到合约漏洞进行分析并形成利用 Ubuntu18.04操作机 python3 在solidity语言中,像动态的数组、struct、mapping这样的复杂数据结构是不能直接在”栈”里面保存的,因为”栈”里只能保存单独的”字”,也就

    2024年02月03日
    浏览(9)
  • Day 42算法记录| 动态规划 08

    Day 42算法记录| 动态规划 08

    单词就是物品,字符串s就是背包 1.dp[0]背包啥也不要用装,true。 2. for循环,顺序很重要,所以先背包再物品 如果求组合数就是外层for循环遍历物品,内层for遍历背包 。 如果求排列数就是外层for遍历背包,内层for循环遍历物品 。 3.递归: 要么装包或者不装 添加链接描述 把

    2024年02月15日
    浏览(15)
  • Day 42 算法记录|动态规划 09 (打家劫舍)

    Day 42 算法记录|动态规划 09 (打家劫舍)

    1.dp[i]:考虑下标i(包括i)以内的房屋,最多可以偷窃的金额为dp[i]。 2.dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]); 3.初始化,dp[0] 和 dp[1],dp[0] 一定是 nums[0],dp[1] = max(nums[0], nums[1]); 3.遍历顺序,dp[i] 是根据dp[i - 2] 和 dp[i - 1] 推导出来的,那么一定是从前到后遍历! 进一步对滚动数组

    2024年02月15日
    浏览(13)
  • IC设计中的DC综合学习记录——模板记录

    IC设计中的DC综合学习记录——模板记录

    一名优秀的IC设计工程师需要懂综合,清楚自己设计的代码与底层的电路的对应关系,明白综合工具对代码的优化方案从而设计出更优PPA(performance,power,area)的电路。同时综合在代码和实际门级电路之间扮演着重要的角色,DC是用于将RTL代码转换成可用于布局布线的网表文

    2024年02月05日
    浏览(12)
  • Echarts中的Map学习记录

    目录 Echarts的Map学习记录 Map介绍 Map配置 geo series visualMap tooltip Map飞线图配置 单点扩散飞线图配置 GeoLines 组件: EffectScatter 组件: Scatter 组件: Map运行轨迹配置 地图数据下载链接整理 Echarts 中的地图(Map)是一种可视化展示地理数据的图表类型,可以用来展示各地区的地理

    2023年04月10日
    浏览(8)
  • C语言学习记录——找数组中的鞍点

    C语言学习记录——找数组中的鞍点

    目录 C语言中 鞍点的定义  代码的实现 思路分析图解  指一个矩阵中,即该位置上的元素在该行上最大,在该列上最小。 一个二维数组可能没有鞍点。 例如:1,2,3            4,5,6            7,8,9 该矩阵中,鞍点为3所在的位置。 即数组坐标[ 0 ] [ 2 ],在第一行第三

    2024年02月04日
    浏览(31)
  • vivado中的FPGA时钟管理单元PLL学习记录

    vivado中的FPGA时钟管理单元PLL学习记录

    FPGA中时钟管理模块(CMT)包括PLL和MMCM,用于将时钟倍频(比如输入时钟25M,我们要产生50M时钟)、分频(在不影响系统功能的前提下,较低的工作时钟,能够降低系统功耗)、改变相位偏移或占空比等。 当需要上板时,由于板上晶振时钟固定,所以其他频率的时钟产生就要用到

    2024年01月16日
    浏览(11)
  • 「我的编程笔记」——记录学习中的代码、函数、概念等

    「我的编程笔记」——记录学习中的代码、函数、概念等

    不管昨天、今天、明天,能豁然开朗就是最美好的一天。 常用代码、特定函数、复杂概念、特定功能……在学习编程的过程中你会记录下哪些内容?快来分享你的笔记,一起切磋进步吧! 编程如同探索一条未知的道路,需要不断地积累、总结和分享经验,才能更加深刻地理

    2024年02月11日
    浏览(13)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包