第9节 构造与析构 – 上

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/pt_raspi_fresher/article/details/88364683

-------------------------------------资源来源于网络,仅供自学使用,如有侵权,联系我必删.

第一:

对象的初始化

  生活中存在的对象都是被初始化后才上市的
  初始状态是对象普遍存在的一个状态的

  一般而言所有的对象都需要一个确定的初始状态
  解决方案
     为每个类都提供一个 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\n", t1.getI());
    printf("t2.i = %d\n", t2.getI());
    printf("t3.i = %d\n", t3.getI());
    
    printf("Press any key to continue...");
    getchar();
    return 0;
}

缺陷:

  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\n", 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;
}

第二:

C++ 中的构造函数

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

class Test
{
private:
    int i;
    int j;
    int k;
    
public:
    //构造函数Test 给 变量赋初值
    Test(int v)
    {
        i = j = k = v;
    }
    
    void print()
    {
        printf("i = %d, j = %d, k = %d\n", i, j, k);
    }
};

  构造函数的调用
     一般情况下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\n", 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;
}

第三:

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

#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\n", i, j, k);
    }
    
    void print(int v)
    {
        printf("v = %d\n", 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;
}

第四:

两个特殊的构造函数

#include <stdio.h>

/*
    注意:
    1. 当类中没有定义任何一个构造函数,C++编译器会为提供无参构造函数和拷贝构造函数
    2. 当类中定义了任意的非拷贝构造函数时,C++编译器不会为提供无参构造函数 
*/

class Test
{ 
public:
    //C++编译器提供默认无参构造函数(形式与下面类似)
    Test()    
    {
        printf("Test()\n");
    }
    
    //C++编译器提供默认拷贝构造函数(形式与下面类似)
    Test(const Test& obj)
    {
        printf("Test(const Test& obj)\n");
    }
};

int main()
{
    Test t1;         //调用没有参数的构造函数  Test()
    Test t2 = t1;    //调用没有参数的构造函数  Test()
    
    printf("Press any key to continue...");
    getchar();
    return 0;
}

两个特殊的构造函数
  无参构造函数
     当类中没有定义构造函数时,编译器默认提供一个无参构造函数,并且其函数体为空
  拷贝构造函数
     当类中没有定义拷贝构造函数时,编译器默认提供一个拷贝构造函数,简单的进行成员变量的值复制

#include <stdio.h>


class Test
{ 
private:
    int i;
    int j;
    int k;
    
public:
    void print()
    {
        printf("i = %d, j = %d, k = %d\n", i, j, k);
    }
};

int main()
{
    Test t1;
    Test t2 = t1;//默认的拷贝构造函数被调用了
    
    t1.print();
    t2.print(); 
    
    printf("Press any key to continue...");
    getchar();
    return 0;
}

第五:

数组类的创建

//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.cpp
#include <stdio.h>
#include "Array.h"

int main()
{
    Array a1(10);//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\n", i, a1.getData(i));//打印0-9
    }
    
    Array a2 = a1;//使用自己写的拷贝构造函数!!!!
    
    for(int i=0; i<a2.length(); i++)
    {
        printf("Element %d: %d\n", i, a2.getData(i));
    }
    
    a1.destory();//释放堆空间
    a2.destory();//
    
    printf("Press any key to continue...");
    getchar();
    return 0;
}

小结

  构造函数是 C++ 中用于初始化对象状态的特殊函数
  构造函数在对象创建时自动被调用
  构造函数和普通成员函数都遵循重载规则
  拷贝构造函数是对象正确初始化的重要保证

猜你喜欢

转载自blog.csdn.net/pt_raspi_fresher/article/details/88364683
今日推荐