c++学习笔记(7.构造与析构)(二)

2014-11-24 02:59:14 · 作者: · 浏览: 4
st int c;这个只读变量来判断,如果这个过程是初始化,c这个成员变量是可以编译通过的,但是这个过程是赋值过程,c又是const属性,所以编译会出错!!! 同时对于t1还可以进行t1 = t2;的操作,这个过程即没有调用有参构造函数,也没有调用拷贝构造函数。是简简单单的把t2的成员变量的值,赋值给t1的成员变量中去!!!但是如果Test t1是一个函数的形参void fun(Test t1),当调用这个函数的时候 fun(t2);,t2当做实参,此时调用了拷贝构造函数!!! 第三:类中的const成员变量时肯定会被分配空间的,只是一个只读变量,因为编译器无法直接得到const成员变量的初始值,因此无法进入符号表成为真正的常量。 第四:初始化与赋值是不同的,这个是在补充第二点,初始化是用已存在的对象或值对正在创建的对象进行初值设置。赋值是用已存在的对象或值对已经存在的对象进行值的设置。

3.c++中的析构函数:

a.c++中在对象撤销的时候,对象会自动调用一个清理函数,与构造函数相对应,叫析构函数。析构函数为~classname(),且没有参数也没有任何返回值类型。 示例代码:
#include 
  
   

class Test
{
private:
    int mI;
public:
    Test(int i) : mI(i)
    {
        printf("Test(), mI = %d\n", mI);
    }
    
    ~Test()
    {
        printf("~Test(), mI = %d\n", mI);
    }
};

void run()
{
    Test t1(1);
    Test t2(2);
}

int main()
{
    run();
    printf("Press any key to continue...");
    getchar();
    
    return 0;
}  
  
注意:析构函数的调用顺序!!! 通过上面的例子,我们发现析构函数的调用顺序是与构造函数的调用顺序完全相反的!!!那我们总结下构造函数的调用顺序: 第一:当类中有成员变量是其他类的对象时,首先调用成员变量的构造函数。(注:调用顺序与声明顺序相同) 第二:调用自身类的构造函数。

4.构造函数与析构函数的关系:

第一点:构造函数与析构函数的产生都是因为,他们可以自动调用(省事),构造函数是类创建对象的时候自动调用的,析构函数是对象销毁的时候自动调用的。 第二点:在某些情况下,c++编译器可以提供默认的构造函数(即无参构造函数和拷贝构造函数),但是析构函数则需要程序员自己手写,编译器提供不了。 第三点:构造函数与析构函数的调用顺序是完全相反的。

课后练习:

1.可以直接调用构造函数吗?

在这里多说几句,首先说说这个问题,这个问题的含义是在main函数或者类的成员函数中,可不可以不通过对象直接调用test(); 这个构造函数,结果是可以编译通过。但是没有对象就直接调用对象里面的成员函数,这也太荒唐了!!!所以编译器此时让构造函数得到了一个临时对象,导致这个构造函数完成不了任何功能!!! 这里还要声明一个问题,就是通过对象来访问对象的构造函数是编译出错的,原因未知!!!总之这个问题有些无趣,荒谬。给个小例子附在后面(可以不看):
#include 
  
   

class Test
{
private:
    int mI;
    int mJ;
    const char* mS;
public:
    Test()
    {
        printf("Test()\n");
        
        mI = 0;
        mJ = 0;
    }
    
    Test(const char* s)
    {
        printf("Test(const char* s)\n");
        
        Test();
        
        mS = s;
    }
    
    ~Test()
    {
        printf("~Test()\n");
    }
    
    void print()
    {
        printf("mI = %d, mJ = %d, mS = %s\n", mI, mJ, mS);
    }
};

void run()
{
    Test t = Test("hello world"); // Test t("hello world");
    
    t.print();
}

int main()
{
    run();
    //Test a;
    //a.Test(); 
    getchar();
    return 0;
}