个人接触这方面有一段时间了,虽知道行浅,但还是愿意讲讲自己对这方面的理解。。也算自己为中国软件事业做点微不足道的小事吧。很多学习程序设计的,大部分都会很急躁,学着学着,越来越发现自己不会的东西越多,于是就否定自己。其实我想说,不管什么只要你认真,踏实就没有做不成的事。人要相信自己,虽说我们这行更新太快,但我们掌握了最核心的又怕什么呢。很多都是相通的。认真理解一个程序的来龙去脉,我觉得比看几本书还有意义。。。。好了,废话说多了,进入今天的主题。谈谈运算符重载、构造析构和引用的一点知识。
多于C++ 来说,一个类只有调用构造函数,才真正意义上分配了内存空间,而对于数据区是一个类私有的,函数接口是共用的。运算符重载不改变运算符的本质含义,只是扩展运算符的功能,我自己编写了一段代码,先上一段图:
定义一个类
class A
{
public:
A(int = 0,int = 0,int = 10); // 构造函数
void Get(); // 数值打印函数
A operator + (A &); // 重载+运算符
A& operator = (A &); // 重载=运算符
const int* GetRuntimeClass() // 标识类信息的地址信息
{
return &classCObject; // 返回标识地址
}
~A() // 析构函数
{
cout<<"析构函数!"<<" -->函数地址:"<<GetRuntimeClass()<<endl;endl;
delete []Wei; // 释放自己开辟的空间
}
private:
int x;
int y;
int Len;
char*Wei;
int classCObject; // 标识类信息,数值我们不关心,只是该变量在类中的地址,并不是类的起始地址
};
这个类主要是为了测试一些基本运行信息设立的,希望对大家理解这方面有一定的帮助。
实现函数
A::A(int a,int b,int len)
{
classCObject = len;
x = a;
y = b;
Wei = new char[len]; // 分配内存空间
cout<<"构造函数!"<<"-->函数地址:"<<GetRuntimeClass()<<endl; // 打印出函数地址信息,方便观察类的内部运行机制
}
void A::Get()
{
cout<<"x = "<<x<<"\ny = "<<y<<endl;
}
// 此处如果返回类型变成引用,入A& A::operator + (A&a) 得不到想要的结果.
A A::operator+(A&a)
{
cout<<"我是加。"<<endl;
return (A(x+a.x,y+a.y,10)); //构造出一个对象
}
A& A::operator = (A &a)
{
x = a.x;
y = a.y;
Len = a.Len;
cout<<"xx = "<<x<<"\nyy = "<<y<<endl;// 调试数值观察
for(int i=0;i<Len;i++)
{
*(Wei+i) = *(a.Wei+i); // 数值的拷贝,当然还可以用strcpy(Wei,a.Wei);
}
cout<<"我是赋值。"<<endl;
return *this; // 此处返回的是类的实例,因为其他标识符要做该类的别名
}
void main()
{
A a(1,2,10),b(3,4,10),c; // 定义对象
// (a+b).Get();
cout<<"a的地址"<<&a<<endl;
c = a+b; // 加法运算符重载,对象之间的浅拷贝
c.Get(); // 输出c对象的私有数据的值
}
截图:
我们定义了3个对象首先就调用3次构造函数,屏幕打印出了3条构造函数信息,之后就执行a+b 调用重载函数,将a,b对象对应的参数相加后,就构造出一个对象,这就是为什么有A& A::operator+(A&a)
{
cout<<"我是加。"<<endl;
return (A(x+a.x,y+a.y,10)); //构造出一个对象
}
是将构造出来的对象,临时对象作为其引用。但应该注意到的一点是,该对象马上就析构了。由于重载了=号运算符,所以得不到该对象。在没用重载=号的情况下,程序图片截图:
在重载了=号的情况下图片:
可以看到程序的值是随机值。我们可以想想,return语句究竟背着我们做了什么。感兴趣的可以自己百度下。
接下来我们谈谈编译器怎样运行语句:
A A::operator+(A&a)
{
cout<<"我是加。"<<endl;
return (A(x+a.x,y+a.y,10)); //构造出一个对象
}
首先我们构造出一个对象,然后将该对象返回给一个临时对象,这是一条语句。所以
编译器发现这两个对象是连续的同一个对象,所以没有必要再分配,编译器就通过计数器i记录引用的次数,通过图片程序:
本来构造出一个对象A(x+a.x,y+a.y,10),函数结束后本来要析构对象的,但由于编译器中计数器就减1,知道重载=号函数结束后,i再减1,对象析构。
希望通过本节的讲解,能够帮助到一些朋友更好的学习。不懂的可以留言,欢迎交流指正。。。 明天就是我生日了,没什么给自己的,祝自己开心快乐。。。。~~~~~~~~~~~~~~~~~~~~~~~~~~~~