• 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++中用于初始化对象状态的特殊函数。

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

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

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

  • 相关阅读:
    面向对象(静态,抽象,接口)--2017-04-20
    面向对象三大特性(面试经常问)--2017-04-18
    析构函数,函数重载,以及面向对象求面积的例子--2017-04-19
    密码强弱的判断(用正则表达式写)---2017-04-17
    php面向对象(一)---2017-04-17
    php数组--2017-04-16
    正则表达式 详解---2017-04-16
    JavaScript BOM 遗漏知识再整理;弹窗和记时事件;
    JavaScript HTML DOM---遗漏知识再整理(向html添加/删除元素,改变内容和css)
    bootstrap部分---网格系统;(几天没写博客了,为了潜心研究一下bootstrap)
  • 原文地址:https://www.cnblogs.com/free-1122/p/11336187.html
Copyright © 2020-2023  润新知