C++ this指针 全部
在每一个成员函数中都包含一个特殊的指针,这个指针的名字是固定的。叫做this。它是指向本类对象的指针,它的值是当前被调用的成员函数所在的对象的起 始地址。例如:当调用成员函数a.volume时,编译系统就把对像a的起始地址赋给this指针,于是在成员函数引用数据成员时,就按照this的指向找到对象a的数 据成员。例如volume函数要计算height*width*length的值,实际上是执行:
(this->height)*(this->width)*(this->length);
由于当前this指向对象a,因此相当于执行:
(a.height)*(a.width)*(a.length);
this指针是隐式使用的,它是作为参数被传递给成员函数的。*this表示被调用的成员函数所在的对象,this*就是this所指向的对象,即当前的对象。例如:在 成员函数a.volume()的函数体中,如果出现*this,它就是本对象a。上面的语句可以使用下面的语句:
return((*this).height*(*this).width*(*this).length);
常对象
如果一个对象被声明为常对象,则不能调用该对象的非const型的成员函数(除了由系统自动调用的隐式的构造函数和析构函数)。例如:
const Time t1(10,15,36); //定义一个常对象t1,并指定数据成员的初值
t1.get_time(); //企图调用对象t1中的非const型的成员函数,非法。。。。
怎么才能引用常对象中的数据成员呢?很简单,只需将该成员函数声明为const即可,如:
void get_time() const; //将函数声明为const;
这就是常成员函数,常成员函数可以访问常对象中的数据成员,但是仍然后允许修改常对象中数据成员的值。如果一定修改常对象中的某个数据成员的值,ANSI C++考虑到实际编程的需要,对此进行了处理,对该数据成员声明为mutable,如:
mutable int count; 把count声明为可变的数据成员,这样就可以用声明为const的成员函数来修改它的值。
常数据成员
只能通过构造函数的参数初始化表对常数据成员进行初始化。例如:
Time::Time(int h)
{ hour=h;}
这样做是非法的,常数据成员不能被赋值。下面这样是正确的:
Time::Time(int h):hour{}
在类体中声明了某个常数据成员后,该类所有对象中的该数据成员的值都是不能改变的,但是不同对象中该成员数据成员的值可以是不同的(在定义对象那时 给定)。
常成员函数
如果将成员函数声明为常成员函数,则只能引用本类中的数据成员,而不能修改它们,例如:
void get_time() const;//注意const的位置在函数名和括号之后;
const是函数类型的一部分,在声明函数和定义函数时都要有关键字const,在调用时不用加。常成员函数可以引用const数据成员,也可以引用非const的数据成员。const数据成员可以被const成员函数引用,也可以被非const的成员引用。
记住:不要认为常对象中的成员函数都是常成员函数。常对象只保障其所有数据成员不被修改。如果在常对象中有成员函数没有加const声明,编译系统把它 作为非const成员函数处理。
指向对象的常指针
将指向对象的指针变量声明为const型,并使之初始化,这样指针值始终保持为其初值,不能改变,即其指向始终不变。如:
Time t1(10,12,15),t2; //定义对象
Time *const ptr1=&t1; //const位置在指针变量名前面,规定ptr1的值是常值。
ptr1=&t2; //错误,ptr1不能改变指向。
定义指向对象的常指针的一般形式:
类名 *const 指针变量名=对象地址;
注意:应在定义指针变量时使之初始化,如
Time *const ptr1;//指定ptr1为指向Time类的指针变量
ptr1=&t1; //使之指向t1,产生编译错误,常指针不能被赋值
什么时候需要使用指向对象的常指针?
如果想将一个指针变量固定地与一个对象相联系(即该指针变量始终指向一个对像),可以将它指定为const型指针变量。
指向常对象的指针变量
定义指向常变量的指针变量的一般形式:
const 类型名 *指针变量名;
如果一个变量已经被声明为常变量,只能用指向常变量的指针变量指向它,而不能用一般的指针指向他。
指向常变量的指针变量除了可以指向常变量外,还可以指向未被声明为const的变量,此时不能通过此指针变量改变该变量的值。
常对象
1.如果一个对象已经被声明为常对象,只能用指向常对象的指针变量指向他,而不能用一般的指针变量去指向它。
2.如果定义了一个指向常对象的指针变量,并使它指向一个非const的对象,则其指向的对象是不能通过指针来改变的。
Time t1(10,12,15); //定义Time类对象t1,它是非const型对象
const Time *p=&t1; //定义p是指向常对象的指针变量,并指向t1
t1.hour=18; //正确,t1不是常变量
(*p).hour=18; //错误,不能通过指针变量改变t1的值。
3.指向常对象的指针最常用于函数的形参,目的是在保护形参指针指向的对象,使它在函数执行过程中不被修改。如
int main()
{
void fun(const Time *p); //形参是指向常对象的指针变量
Time t1(10,12,30); //定义Time类对象t1,他不是常对象
fun(&t1); //实参是对象t1的地址
return 0;
}
void fun()
{
p->hour=18; //错误
cout<<p->hour<<endl;
}
对象的常引用
一个变量的引用就是变量的别名。实际上,变量名和引用名都是用同一段内存单元。
#include <iostream>
using namespace std;
class Time
{
public:
Time(int,int,int);
int hour;
int minute;
int sec;
};
Time::Time(int h,int m,int s)
{
hour=h;
minute=m;
sec=s;
}
void fun(Time &t)
{t.hour=18;}
int main()
{
Time t1(10,13,56);
fun(t1);
cout<<t1.hour<<endl;
return 0;
}
对象的动态建立
如果已经定义了一个Box类,可以用下面的方法动态建立一个对象:
new Box;
用new运算符动态的分配内存后,将返回一个指向新对象的指针的值,即所分配的内存空间的起始地址。用户可以获得这个地址,并通过这个地址来访问这 个对象,需要定义一个指向本类的对象的一个指针变量来存放改地址。如:
Box *pt; //定义一个指向Box类对象的指针变量pt
pt=new Box; //在pt中存放了新建对象的起始地址
在程序中,可以通过pt访问这个新建的对象,
cout<<pt->height; //输出该对象的height成员
cout<<pt->volume(); //调用该对象的volume函数,计算并输出体积
C++还允许在执行new时,对新建的对象进行初始化,如
Box *pt=new Box(12,15,55);
调用对象既可以通过对象名,也可以通过指针,用new建立的动态对象一般是不用对象名的,而是通过指针访问的。它主要用于动态的数据结构,如链表。
在执行new运算符时,如果内存量不足,无法开辟所需的内存空间。目前大多数C++编译器都会使new返回一个0指针值。只要检测返回值是否为0,就可以 分配内存是否成功。
C++ this指针 全部的更多相关文章
- TODO:Golang指针使用注意事项
TODO:Golang指针使用注意事项 先来看简单的例子1: 输出: 1 1 例子2: 输出: 1 3 例子1是使用值传递,Add方法不会做任何改变:例子2是使用指针传递,会改变地址,从而改变地址. ...
- enote笔记法使用范例(2)——指针(1)智能指针
要知道什么是智能指针,首先了解什么称为 “资源分配即初始化” what RAII:RAII—Resource Acquisition Is Initialization,即“资源分配即初始化” 在&l ...
- C++虚函数和函数指针一起使用
C++虚函数和函数指针一起使用,写起来有点麻烦. 下面贴出一份示例代码,可作参考.(需要支持C++11编译) #include <stdio.h> #include <list> ...
- C++11 shared_ptr 智能指针 的使用,避免内存泄露
多线程程序经常会遇到在某个线程A创建了一个对象,这个对象需要在线程B使用, 在没有shared_ptr时,因为线程A,B结束时间不确定,即在A或B线程先释放这个对象都有可能造成另一个线程崩溃, 所以为 ...
- c 数组与指针的使用注意事项
数组变量和指针变量有一点小小的区别 所以把数组指针赋值给指针变量的时候千万要小心 加入把数组赋值给指针变量,指针变量只会包含数组的地址信息 而对数组的长度一无所知 相当于指针丢失了一部分信息,我们把这 ...
- Marshal.Copy将指针拷贝给数组
lpStatuss是一个UNITSTATUS*的指针类型实例,并包含SensorDust字段 //定义一个数组类型 byte[] SensorDust = new byte[30] //将指针类型拷贝 ...
- C++智能指针
引用计数技术及智能指针的简单实现 基础对象类 class Point { public: Point(int xVal = 0, int yVal = 0) : x(xVal), y(yVal) { ...
- EC笔记:第三部分:17、使用独立的语句将newed对象放入智能指针
一般的智能指针都是通过一个普通指针来初始化,所以很容易写出以下的代码: #include <iostream> using namespace std; int func1(){ //返回 ...
- 智能指针shared_ptr的用法
为了解决C++内存泄漏的问题,C++11引入了智能指针(Smart Pointer). 智能指针的原理是,接受一个申请好的内存地址,构造一个保存在栈上的智能指针对象,当程序退出栈的作用域范围后,由于栈 ...
- 智能指针unique_ptr的用法
unique_ptr是独占型的智能指针,它不允许其他的智能指针共享其内部的指针,不允许通过赋值将一个unique_ptr赋值给另一个unique_ptr,如下面错误用法: std::unique_pt ...
随机推荐
- 微信小程序animation
wxml <view class="background" animation="{{rotateData}}"> </view>< ...
- 生成元(Digit Generator, ACM/ICPC Seoul 2005, UVa1583)
如果x加上x的各个数字之和得到y,就说x是y的生成元.给出n(1≤n≤100000),求最小 生成元.无解输出0.例如,n=216,121,2005时的解分别为198,0,1979. [分析] 本题看 ...
- Python变量的命名 单下划线和双下划线
python命名变量的区别 foo: 一种约定,Python内部的名字,用来区别其他用户自定义的命名,以防冲突,就是例如__init__(),__del__(),__call__()这些特殊方法 _f ...
- 《零压力学Python》 之 第一章知识点归纳
第一章(初识Python)知识点归纳 Python是从ABC语言衍生而来的 ABC语言是Guido参与设计的一种教学语言,为非专业编程人员所开发的. Python是荷兰程序员 Guido Van Ro ...
- 2.2 为什么要使用Shell脚本
使用脚本编程语言的好处是,它们多半运行在比编译型语言还高的层级,能够轻易处理文件与目录之类的对象.缺点是:它们的效率通常不如编译型语言.不过权衡之下,通常使用脚本编程还是值得的:花一个小时写成 ...
- 清北学堂模拟赛d1t3 听音乐(music)
题目描述 LYK喜欢听音乐,总共有n首音乐,有m个时刻,每个时刻LYK会听其中一首音乐,第i个时刻会听第ai首音乐.它给自己定了一个规定,就是从听音乐开始,听的每连续n首音乐都是互不相同的.例如当n= ...
- [bzoj1812][IOI2006]riv_多叉树转二叉树_树形dp
riv bzoj-1812 IOI-2006 题目大意:给定一棵n个点树,要求在上面建立k个收集站.点有点权,边有边权,整棵树的代价是每个点的点权乘以它和它的最近的祖先收集站的距离积的和. 注释:$1 ...
- N天学习一个Linux命令之top
用途 查看机器负载以及进程资源占用情况,linux系统性能分析工具 用法 top -hv | -abcHimMsS -d delay -n iterations -p pid [, pid ...] ...
- Clojure:解决korma中mysql utf8的问题
当使用korma内置的mysql方法时,无法添加utf-8的支持.解决的方法就是重写mysql方法,代码如下: (defn mysql "改编自korma,添加了utf-8的支持" ...
- Java对二叉搜索树进行插入、查找、遍历、最大值和最小值的操作
1.首先,须要一个节点对象的类.这些对象包括数据.数据代表存储的内容,并且还有指向节点的两个子节点的引用 class Node { public int iData; public double dD ...