C++--第9课

第9课 - 构造与析构 - 上

1. 对象的初始化

生活中存在的对象都是被初始化后才上市的,初始状态是对象普遍存在的一个状态的。一般而言所有的对象都需要一个确定的初始状态。

解决方案:

为每个类都提供一个public的initialize函数;对象创建后立即调用initialize函数进行初始化。

#include <stdio.h>

class Test

{

private:

    int i;

public:

    void initialize()

    {

        i = 0;

    }

    

    int getI()

    {

        return i;

    }

};

int main()

{

    Test t1;

    Test t2;

    Test t3;

   

    t1.initialize();

    t2.initialize();

    t3.initialize();

   

    printf("t1.i = %d ", t1.getI());

    printf("t2.i = %d ", t2.getI());

    printf("t3.i = %d ", t3.getI());

   

    printf("Press any key to continue...");

    getchar();

    return 0;

}

运行结果,各个变量的值都变成了1。

initialize只是一个普通的函数,必须显示的调用。一旦由于失误的原因,对象没有初始化,那么结果将是不确定的。没有初始化的对象,其内部成员变量的值是不定的。

#include <stdio.h>

class Test

{

private:

    int i;

    int j;

    int k;

   

public:

    void initialize()

    {

        i = 0;

        j = 0;

        k = 0;

    }

   

    void print()

    {

        printf("i = %d, j = %d, k = %d ", i, j, k);

    }

};

int main()

{

    Test t1;

    Test t2;

    Test t3;

   

    t1.print();

    t2.print();

    t3.print();

   

    printf("Press any key to continue...");

    getchar();

    return 0;

}

运行结果,各个变量的值不定。

2. C++中的构造函数

C++中的类可以定义与类名相同的特殊成员函数;这种与类名相同的成员函数叫做构造函数;构造函数在定义时可以有参数,但是没有任何返回类型的声明。

class Test

{

private:

int i;

int j;

int k;

public:

Test(int v)

{

i = j = k =v;

}

......

}

l  构造函数的调用

一般情况下C++编译器会自动调用构造函数,在一些情况下则需要手工调用构造函数。

#include <stdio.h>

class Test

{

private:

    int i;

    int j;

    int k;

   

public:

    Test(int v)

    {

        i = v;

        j = v;

        k = v;

    }

   

    void print()

    {

        printf("i = %d, j = %d, k = %d ", i, j, k);

    }

};

int main()

{

    Test t1(4);  //自动调用构造函数

    Test t2 = 5;  //自动调用构造函数

    Test t3 = Test(6);  //主动调用构造函数

   

    t1.print();

    t2.print();

    t3.print();

   

    Test tA[3] = {Test(1), Test(2), Test(3)};  //主动调用构造函数,不手动写会报错。

   

    for(int i=0; i<3; i++)

    {

        tA[i].print();

    }

   

    printf("Press any key to continue...");

    getchar();

    return 0;

}

运行结果:

i = 4, j = 4, k =4

i = 5, j = 5, k =5

i = 6, j = 6, k =6

i = 1, j = 1, k =1

i = 2, j = 2, k =2

i = 3, j = 3, k =3

l  成员函数的重载

类的成员函数和普通函数一样可以进行重载,并遵守相同的重载规则。

#include <stdio.h>

class Test

{

private:

    int i;

    int j;

    int k;  

public:

    Test()

    {

        i = 0;

        j = 0;

        k = 0;

    } 

    Test(int v)

    {

        i = v;

        j = v;

        k = v;

    } 

    void print()

    {

        printf("i = %d, j = %d, k = %d ", i, j, k);

    }  

    void print(int v)

    {

        printf("v = %d ", v);

    }

};

int main()

{

    Test t1(4);

    Test t2 = 5;

    Test t3 = Test(6);

    Test t4;  

    t4.print();

    t1.print();

    t2.print();

    t3.print();  

    Test tA[3];   

    for(int i=0; i<3; i++)

    {

        tA[i].print();

    } 

    printf("Press any key to continue...");

    getchar();

    return 0;

}

运行结果:

i = 0; j = 0; k = 0

i = 4; j = 4; k = 4

i = 5; j = 5; k = 5

i = 6; j = 6; k = 6

i = 0; j = 0; k = 0

i = 0; j = 0; k = 0

i = 0; j = 0; k = 0

定义数组没有初始化,Test tA[3]使用了没有参数的构造函数。

3. 两个特殊的构造函数

#include <stdio.h>

/*

    注意:

    1. 当类中没有定义任何一个构造函数,C++编译器会为提供无参构造函数和拷贝构造函数

    2. 当类中定义了任意的非拷贝构造函数时,C++编译器不会为提供无参构造函数

*/

class Test

{

public:

    Test()

    {

        printf("Test() ");

    }

    Test(const Test& obj)

    {

        printf("Test(const Test& obj) ");

    }

};

int main()

{

    Test t1;

    Test t2 = t1; 

    printf("Press any key to continue...");

    getchar();

    return 0;

}

运行结果:

Test<>

Test<const Test& obj>

无参构造函数

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

拷贝构造函数

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

#include <stdio.h>

class Test

{

private:

    int i;

    int j;

    int k; 

public:

    void print()

    {

        printf("i = %d, j = %d, k = %d ", i, j, k);

    }

};

int main()

{

    Test t1;

    Test t2 = t1; 

    t1.print();

    t2.print();  

    printf("Press any key to continue...");

    getchar();

    return 0;

}

运行结果:

i = 4200582, j = 2686760, k =4200678

i = 4200582, j = 2686760, k =4200678

编译器提供的复制函数,将对应函数一一赋值。

4. 写代码--创建数组类

Array.h

#ifndef _ARRAY_H_

#define _ARRAY_H_

class Array

{

private:

    int mLength;

    int* mSpace;

public:

    Array(int length);

    Array(const Array& obj);

    int length();

    void setData(int index, int value);

    int getData(int index);

    void destory();

};

#endif

Array.cpp

#include "Array.h"

Array::Array(int length)

{

    if( length < 0 )

    {

        length = 0;

    }

   

    mLength = length;

    mSpace = new int[mLength];

}

Array::Array(const Array& obj)

{

    mLength = obj.mLength;

   

    mSpace = new int[mLength];

   

    for(int i=0; i<mLength; i++)

    {

        mSpace[i] = obj.mSpace[i];

    }

}

int Array::length()

{

    return mLength;

}

void Array::setData(int index, int value)

{

    mSpace[index] = value;

}

int Array::getData(int index)

{

    return mSpace[index];

}

void Array::destory()

{

    mLength = -1;

    delete[] mSpace;

}

main.c

#include <stdio.h>

#include "Array.h"

int main()

{

    Array a1(10);

   

    for(int i=0; i<a1.length(); i++)

    {

        a1.setData(i, i);

    }

   

    for(int i=0; i<a1.length(); i++)

    {

        printf("Element %d: %d ", i, a1.getData(i));

    }

   

    Array a2 = a1;

   

    for(int i=0; i<a2.length(); i++)

    {

        printf("Element %d: %d ", i, a2.getData(i));

    }

   

    a1.destory();

    a2.destory();

   

    printf("Press any key to continue...");

    getchar();

    return 0;

}

小结:

构造函数是C++中用于初始化对象状态的特殊函数。

构造函数在对象创建时自动被调用。

构造函数和普通成员函数都遵循重载规则。

拷贝构造函数是对象正确初始化的重要保证。

原文地址:https://www.cnblogs.com/free-1122/p/11336187.html