#include<iostream>
using namespace std;
class X{int m;int& r;int* p;
public:X(int mm =0):m(mm),r(m),p(&m){}voidchangep(){*p =10;}voidchanger(){ r =5;}intgetm(){return m;}};intmain(){
X a;
X b(a);
cout<<a.getm()<<endl;
b.changep();
cout<<a.getm()<<endl;
b.changer();
cout<<a.getm()<<endl;return0;}
错误原因就是浅拷贝函数把b的 r 和 p 都赋成了a中m的地址。
我们这时要自己定义一个构造函数
X(X& a):m(a.m),r(m),p(&m){}
拷贝构造函数在如下情况下会被调用
voidf(X obj){}
X g(){
Y obj;return obj;}intmain(){
Y a;
Y b = a;//等价于b(a),调用f(a);//参数按值传递,调用
b =g();//参数按值返回,调用}
后两种情况都是按值返回时才调用,引用传递和返回时不会调用。
析构函数
析构函数在对象生命周期结束时或用delete释放时,析构函数会自动被调用。
析构函数的名字是类名字前加波浪线~
析构函数和构造函数一样,没有返回值类型。
析构函数不能重载,只能定义唯一一个析构函数。
实例
设计一个平面线类,要求
线有两个点确定
点由其横坐标和纵坐标确定
可以通过改变点的坐标改变线段位置
可以得到线段长度
不可以使用友元
#include<iostream>#include<cmath>
using namespace std;
class Point{double x,y;
public:Point(double x =0,double y =0){
this -> x = x;
this -> y = y;}voidsetx(double xx){ x = xx;}voidsety(double yy){ y = yy;}doublegetx(){return x;}doublegety(){return y;}voidgetPoint(){
cout<<'('<<x<<','<<y<<')';}};
class Line{
Point a,b;
public:Line(Point aa,Point bb):a(aa),b(bb){}voidchangePointStart(double xx,double yy){
a.setx(xx); a.sety(yy);}voidchangePointEnd(double xx,double yy){
b.setx(xx); b.sety(yy);}voidgetLine(){
cout<<"直线由"; a.getPoint();b.getPoint();
cout<<"组成,长度为"<<getLong()<<endl;}doublegetLong(){double detax,detay;
detax = a.getx()- b.getx(); detay = a.gety()- b.gety();returnsqrt(detax * detax + detay * detay);}};intmain(){
Point a,b(3,4);
Point c = b;
cout<<"初始值为a"; a.getPoint();cout<<",b"; b.getPoint();
cout<<",c"; c.getPoint(); cout<<endl;
Line l1(a,b);
l1.getLine();
Line l2 = l1;
l2.changePointStart(8,10);
l2.getLine();return0;}