首页 > 其他 > 详细

构造函数和析构函数

时间:2020-05-28 15:02:23      阅读:40      评论:0      收藏:0      [点我收藏+]

构造函数定义及调用

   1)C++中的类可以定义与类名相同的特殊成员函数,这种与类名相同的成员函数叫做构造函数;

   2)构造函数在定义时可以有参数;

   3)没有任何返回类型的声明;

 

构造函数定义及调用

   1)C++中的类可以定义一个特殊的成员函数清理对象,这个特殊的成员函数叫析构函数,语法:~ClassName();

   2)析构函数没有参数也没有任何返回类型的声明;

   3)析构函数在对象销毁时自动被调用;

 

默认构造函数

   二个特殊的构造函数

   1)默认无参构造函数:当类中没有定义构造函数时,编译器默认提供一个无参构造函数,并且其函数体为空。

   2)默认拷贝构造函数:当类中没有定义拷贝构造函数时,编译器默认提供一个默认拷贝构造函数,简单的进行成员变量的值复制。

 

构造函数调用规则

   1)当类中没定义任何构造函数时,C++编译器会提供默认无参构造函数和默认拷贝构造函数。

   2)当类中定义了拷贝构造函数时,C++编译器不会提供无参数构造函数。

   3) 当类中定义了任意的非拷贝构造函数(即:当类中提供了有参构造函数或无参构造函数),C++编译器不会提供默认无参构造函数。

   4)默认拷贝构造函数进行的是浅拷贝。

 

构造函数的分类及调用

   我们来看如下代码:

class Test
{
private:
    int a, b;

public:
    Test() {}                  // 无参数构造函数
    Test(int a, int b) {}      // 带参数的构造函数
    Test(const Test &obj) {}   // 赋值构造函数

public:
    void init(int _a, int _b)
    {
        a = _a;
        b = _b;
    }
};

   1)无参数构造函数:调用方法如下

Test t1, t2;
Test t1 = Test();        // 这样才是调用默认构造函数,这时必须带有括号

   2)带参数构造函数

Test t1(20, 10);         // 括号法: C++编译器默认调用有参构造函数 
Test t2 = (20, 10);      // 等号法: C++编译器默认调用有参构造函数
Test t3 = Test(20, 10);  // 直接调用构造构造函数法: 程序员手工调用构造函数产生了一个对象

   3)赋值(拷贝)构造函数:下面介绍赋值构造函数的三种调用场景(调用时机)。

      a. 用对象1初始化对象2

class Test
{
public:
    Test() { cout << "我是构造函数,自动被调用了" << endl; }
    Test(int _a) : a(_a) {}
    Test(const Test &obj2) { cout << "我也是构造函数,我是通过另外一个对象obj2,来初始化我自己" << endl; }
    ~Test() { cout<<"我是析构函数,自动被调用了"<<endl; }

private:
    int a;
};

int main()
{
    Test a1;
    Test a2 = a1; // 用 a1 初始化 a2
    Test a3(a1);  // 这样写也是用 a1 初始化 a3
    return 0;
}

      b. 实参变量初始化形参变量

class Location 
{ 
public:
    Location(int x = 0, int y = 0) : X(x), Y(y) { cout << "Constructor Object.\n"; }
    Location(const Location &p) : X(p.X), Y(p.Y) { cout << "Copy_constructor called." << endl; }
    ~Location() { cout << X << "," << Y << " Object destroyed." << endl; }
    int GetX () { return X; }     
    int GetY () { return Y; }

private:
    int X, Y;
};

void f(Location  p)   
{ 
    cout << "Funtion:" << p.GetX() << "," << p.GetY() << endl; 
}

int main()
{  
    Location A(1, 2);
    f(A);  // 调用f会构造一个临时对象p,此时会调用拷贝构造函数
    return 0;
}

      c. 函数返回匿名对象,会在栈上面通过拷贝构造函数产生一个临时对象(一般会被优化),那之后就取决于程序员怎么来接收这个匿名对象。

class Location 
{ 
public:
    Location(int x = 0, int y = 0) : X(x), Y(y) { cout << "Constructor Object.\n"; }
    Location(const Location &p) : X(p.X), Y(p.Y) { cout << "Copy_constructor called." << endl; }
    ~Location() { cout << X << "," << Y << " Object destroyed." << endl; }
    int GetX () { return X; }     
    int GetY () { return Y; }

private:
    int X, Y;
};

void f(Location p)   
{ 
    cout << "Funtion:" << p.GetX() << "," << p.GetY() << endl; 
}

/*
 * 当函数需要返回一个对象,他会在栈中创建一个临时对象,存储函数的返回值。
 * 这个临时对象也是匿名对象,构造它时会调用拷贝构造函数,用A来初始化这个匿名对象。
 * 然后函数调用结束,A被销毁.
 * 但是这个临时对象的构造一般会被编译器优化掉,所以自己测试的时候一般不会调用拷贝构造函数了。 
 */
Location g()
{
    Location A(1, 2);
    return A;
}


int main()
{  
    Location B;
    B = g();           // 若返回的匿名对象,赋值给另外一个同类型的对象,那么匿名对象会被析构
    Location C = g();  // 若返回的匿名对象,来初始化另外一个同类型的对象,那么匿名对象会直接转成新的对象
    return 0;
}

 

构造函数和析构函数

原文:https://www.cnblogs.com/yanghh/p/12980542.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!