当前位置: 首页 > article >正文

c++的this指针与常函数

this指针与常函数

成员函数是如何区别调用它的对象?
#include <iostream>
using namespace std;
​
class Test
{
    const int num;
public:
    Test(int num):num(num) {}
    void show(void)
    {
        cout << num << " " << &num << endl;
    }
};
​
int main(int argc,const char* argv[])
{
    Test t1(1234), t2(5678);
    t1.show();
    t2.show();
}
C语言中我们如何解决该问题:

由于C语言中的结构没有成员函数,只能定义普通函数,取函数名时,让它与结构有关联,然后在函数的第一个参数把结构变量的地址传递过来,从而区别每个调用它的结构变量。

在C++语言中该问题由编译器帮忙解决:

1、C++语言中的结构、联合、类可以定义成员函数,成员函数都会有一个隐藏的参数。

2、该参数就是个地址,也叫this指针,可以显式使用。

3、使用结构、联合、类对象可以直接调用成员函数时,编译器会自动计算对象的地址隐式的传递给成员函数。

4、所以在成员函数中可以区分是哪个对象调用了它,并且在成员函数内访问成员变量时,编译器帮我们隐式在每个成员变量前增加了this->,所以可以区别出每个对象的成员变量。

5、由于成员函数参数列表中都隐藏着this指针,所以普通的成员函数无法作为回调函数使用。

#include <iostream>
#include <pthread.h>
#include <signal.h>
using namespace std;
​
class Test
{
    int num;
public:
    Test(int num):num(num){ }
​
    void* run(Test* this,void* arg)
    {   
​
    }   
    
    void sigint(int signum)
    {   
​
    }   
​
    void show(void)
    {   
        cout << num << " " << &num << endl;
    }   
};
​
int main(int argc,const char* argv[])
{
    signal(SIGINT,Test::sigint);
​
    pthread_t tid;
    pthread_create(&tid,NULL,Test::run,NULL);
​
    return 0;
}

6、显式使用this指针可以解决函数参数与成员变量同名的问题。

#include <iostream>
#include <pthread.h>
#include <signal.h>
using namespace std;
​
class Test
{
    int num;
public:
    Test(int num):num(num){ }
    void setNum(int num)
    {
        this->num = num;
        cout << this->num << " - " << &this->num << endl;
    }
​
    void show(void)
    {
        cout << num << " " << &num << endl;
    }
};
​
int main(int argc,const char* argv[])
{
    Test t1(1234), t2(5678);
    t1.show();
    t2.show();
    t1.setNum(6666);
    t1.show();
}
常对象与常函数
什么是常函数

在成员函数的参数列表的末尾(小括号后面),用const修饰,这种成员就叫常函数。

class 类名
{
public:
    // 常函数
    返回值 函数名(参数列表) const
    {
        
    }
};
常函数的特点:

常函数隐藏的this指针具有cosnt属性。

什么是常对象

在定义结构、联合、类对象时,使用const修饰,这种对象就叫常对象。

const 类名 对象名;
const 类名* 指针变量 = new 类名;
常对象的特点:

使用常对象调用成员函数时,编译器计算出的对象地址(this)也具有const属性。

常对象有常函数的局限性:

1、常对象不能调用普通成员函数,只能调用常函数(构造函数和析构函数除外),但普通对象既可以普通成员函数,也可以调用常函数。

2、在常函数中不能显式修改成员变量,并且也不能调用普通的成员函数,只能调用常函数。

3、如果类的对象一定会被const修饰,那么它的成员函数都要定义为常函数。

4、如果类的对象可能被const修饰,也可能不修饰,那么它的成员函数要写两份,一份常函数,另一份普通成员函数。

mutable关键字的作用

如果常函数的const属性与函数的功能发生冲突,一定要修改成员变量,那么使用mutable关键字修饰一下需要在常函数中修改的成员变量。

#include <iostream>
#include <pthread.h>
#include <signal.h>
using namespace std;
​
class Test
{
    mutable int num;
public:
    Test(int num):num(num){ }
​
    void setNum(int num) const
    {
        this->num = num;
        cout << this->num << " - " << &this->num << endl;
    }
​
    void show(void) const
    {
        cout << num << " " << &num << endl;
    }
};
​
int main(int argc,const char* argv[])
{
    const Test t(1234);
    t.show();
    t.setNum(23456);
    t.show();
​
    return 0;
}
空类的对象为什么占用1字节内存?

1、因为C++中的空的结构、联合、类里面有隐藏的成员函数。

2、成员函数的参数列表中有隐藏this指针,调用这些成员函数时就需要计算出对象的地址传递给成员函数。

3、空的类对象至少要在内存中占据一个字节,才可以计算出this指针,传递成员函数,完成函数调用。


http://www.kler.cn/news/302443.html

相关文章:

  • Mysql 搭建主从复制
  • 期货赫兹量化-种群优化算法:进化策略,(μ,λ)-ES 和 (μ+λ)-ES
  • 【学习归纳自我总结版】尚硅谷学习第二天
  • FreeBSD兼容模式linux账户指向FreeBSD账户造成的困扰
  • udp聊天室
  • 【50 Pandas+Pyecharts | 暑期档电影票房数据分析可视化】
  • 深入探讨 Flannel 技术:性能、缺陷与优点
  • sql格式化工具
  • MongoDB 原子操作
  • 【计算机网络】UDP 协议详解及其网络编程应用
  • vue3中实现拖拽排序(vue-draggable-next的使用)
  • SVM 监督学习
  • Linux CentOS更换阿里云源解决Could not retrieve mirrorlist http://mirrorlist.centos.org
  • 电脑监控软件系统有哪些?|2024年干货整理,赶紧码住!
  • css父容器溢出隐藏 子容器溢出滚动
  • 使用TLS解决Docker API暴露2375端口的问题
  • C++-----STL简介(了解)
  • 【数据结构】第八节:链式二叉树
  • 为什么学习Python数据分析?学会能干什么?python数据分析有什么用
  • 研1日记10
  • 保证缓存一致性
  • Debian11.9镜像基于jre1.8的Dockerfile
  • ppt图标去哪找?自带素材库的在线PPT软件,免费获取!
  • Caffenie配合Redis做两级缓存,Redis发布订阅实现缓存一致更新
  • 关于支付宝小程序客户端退出不了的问题的认知和退出的解决方案
  • Object Pascal 基本数据类型
  • 宝马销量崩了,自己作死拦都拦不住
  • 压测服务器并使用 Grafana 进行可视化
  • (不用互三)AI绘画工具大比拼:Midjourney VS Stable Diffusion该如何选择?
  • 【JUC】16-Java对象内存布局和对象头