這些函數在網上很容易就可以查到定義和寫法,這裡就不贅述了。令人感興趣的是這些函數什麼時候執行, 特别是複制構造函數和析構函數。
用編寫的一段(很醜的)代碼來說明。
#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...
傳遞引用可以減少很多不必要的構造, 節省記憶體空間, 同時也提高效率。