这些函数在网上很容易就可以查到定义和写法,这里就不赘述了。令人感兴趣的是这些函数什么时候执行, 特别是复制构造函数和析构函数。
用编写的一段(很丑的)代码来说明。
#include<iostream>
#include<cstdio>
#include<cmath>
class Point
{
private:
/* data */
double x, y ;
friend Point& __doa(Point *ths, const Point& p) ;
public:
Point(double x=0, double y=0)
: x(x), y(y)
{
std::cout<<"Creating a Point...\n" ;
}
Point (const Point& obj){
*this = obj ;
std::cout<<"Copying a Point...\n" ;
}
~Point(){
std::cout<<"Deleting a Point...\n" ;
}
double get_x() const {return x;}
double get_y() const {return y;}
};
// Point&
// __doa(Point *ths, const Point& p ){
// ths->x = p.x ;
// ths->y = p.y ;
// return *ths ;
// }
// Point&
// Point::operator = (const Point& p){
// return __doa(this, p) ;
// }
double dist(Point A, Point B) {
// 返回A和B的euclid距离
double dist_x = A.get_x() - B.get_x() ;
double dist_y = A.get_y() - B.get_y() ;
return sqrt(dist_x*dist_x + dist_y*dist_y) ;
}
class Circle
{
private:
/* data */
Point c ;
double r ;
public:
Circle(Point c, double r=0)
: c(c), r(r)
{
std::cout<<"Creating a Circle...\n" ;
}
Circle(const Circle& obj){
*this = obj ;
std::cout<<"Copying a Circle...\n" ;
}
~Circle(){
std::cout<<"Deleting a Circle...\n" ;
}
Point get_c() const {return c ; }
double get_r() const {return r; }
};
bool is_intersect(Circle O1,Circle O2){
std::cout<<"\n" ;
Point c1, c2 ;
c1 = O1.get_c() ;
c2 = O2.get_c() ;
return O1.get_r() +O2.get_r() > dist(c1, c2) ;
}
int main(){
Point A(1,0), B(0,1) ;
std::cout<<"\n" ;
std::cout<<dist(A,B)<<"\n";
std::cout<<"\n" ;
Circle C1(Point(1,0), 2), C2(Point(4,0), 1.2);
std::cout<<"\n" ;
std::cout<<is_intersect(C1, C2)<<"\n" ;
std::cout<<"\n" ;
C1.get_c() ;
std::cout<<"\n" ;
return 0 ;
}
输出信息:
# 创建A和B
Creating a Point...
Creating a Point...
# dist创建形参并且销毁
Copying a Point...
Copying a Point...
1.41421
Deleting a Point...
Deleting a Point...
#创建Circle的时候,首先创建临时的Point, 然后通过copy复制创建Circle的c, 创建Circle,最后删掉临时的Point
Creating a Point...
Copying a Point...
Creating a Circle...
Deleting a Point...
Creating a Point...
Copying a Point...
Creating a Circle...
Deleting a Point...
# is_intersect先创建形参Circle的c,然后通过copy复制创建形参
Creating a Point...
Copying a Circle...
Creating a Point...
Copying a Circle...
# 创建c1,c2, 使用函数get_c 会copy一个实例出来,然后返回,删掉。然后给dist传参,这时候要创建形参,用完删掉。删掉c1,c2. 最后删掉O1, O2(当然删掉Circle之后要把c也删掉).
Creating a Point...
Creating a Point...
Copying a Point...
Deleting a Point...
Copying a Point...
Deleting a Point...
Copying a Point...
Copying a Point...
Deleting a Point...
Deleting a Point...
Deleting a Point...
Deleting a Point...
1
Deleting a Circle...
Deleting a Point...
Deleting a Circle...
Deleting a Point...
# 可以看到,调用get_c也会使用复制构造函数
Copying a Point...
Deleting a Point...
# 最后删掉main中创建的实例(按照创建时间倒序删除,看来是堆栈)
Deleting a Circle...
Deleting a Point...
Deleting a Circle...
Deleting a Point...
Deleting a Point...
Deleting a Point...
从上面的输出信息可以发现这么几点:
- 构造使用了自底向上的顺序, 而析构使用了自顶向下的顺序。 比如给函数is_intersect传递形参的时候, 需要先创建一个Point, 也就是c. 因为copy函数是将所有的属性进行复制, 而没有Point这个属性的话是无法进行的。
- 传递形参, 创建返回值的时候, 经常使用到复制构造函数。 比如像dist函数传递形参的过程中。 还有get_c函数返回对象c, 即使只有简单的一条语句, 也创建了一个新的对象。
- 从函数中退出的时候, 本地产生的对象都会被析构, 释放内存。
下面的代码段是给函数尽可能加上引用之后的形式, 为了进行比较, 也输出了相应的信息。
#include<iostream>
#include<cstdio>
#include<cmath>
class Point
{
private:
/* data */
double x, y ;
public:
Point(const double& x=0, const double& y=0)
: x(x), y(y)
{
std::cout<<"Creating a Point...\n" ;
}
Point (const Point& obj){
*this = obj ;
std::cout<<"Copying a Point...\n" ;
}
~Point(){
std::cout<<"Deleting a Point...\n" ;
}
double get_x() const {return x;}
double get_y() const {return y;}
};
double dist(const Point& A,const Point& B) {
// 返回A和B的euclid距离
double dist_x = A.get_x() - B.get_x() ;
double dist_y = A.get_y() - B.get_y() ;
return sqrt(dist_x*dist_x + dist_y*dist_y) ;
}
class Circle
{
private:
/* data */
Point c ;
double r ;
public:
Circle(const Point& c, const double& r=0)
: c(c), r(r)
{
std::cout<<"Creating a Circle...\n" ;
}
Circle(const Circle& obj){
*this = obj ;
std::cout<<"Copying a Circle...\n" ;
}
~Circle(){
std::cout<<"Deleting a Circle...\n" ;
}
Point get_c() const {return c ; }
double get_r() const {return r; }
};
bool is_intersect(const Circle& O1,const Circle& O2){
std::cout<<"\n" ;
return O1.get_r() +O2.get_r() > dist(O1.get_c(), O2.get_c()) ;
}
int main(){
Point A(1,0), B(0,1) ;
std::cout<<"\n" ;
std::cout<<dist(A,B)<<"\n";
std::cout<<"\n" ;
Circle C1(Point(1,0), 2), C2(Point(4,0), 1.2);
std::cout<<"\n" ;
std::cout<<is_intersect(C1, C2)<<"\n" ;
std::cout<<"\n" ;
C1.get_c() ;
std::cout<<"\n" ;
return 0 ;
}
Creating a Point...
Creating a Point...
1.41421
Creating a Point...
Copying a Point...
Creating a Circle...
Deleting a Point...
Creating a Point...
Copying a Point...
Creating a Circle...
Deleting a Point...
Copying a Point...
Copying a Point...
Deleting a Point...
Deleting a Point...
1
Copying a Point...
Deleting a Point...
Deleting a Circle...
Deleting a Point...
Deleting a Circle...
Deleting a Point...
Deleting a Point...
Deleting a Point...
传递引用可以减少很多不必要的构造, 节省内存空间, 同时也提高效率。