开篇前先说个小感慨吧
时间过的很快,一转眼今天已经是2018年下半年的第一天了,莫名的,突然有种强烈的紧迫感,感觉时间不够用,小伙伴们,大家还记得年初我们给自己定下的小目标吗?时间已经过去了一半,你是否还是一如既往的在路上呢?不管怎样,一定要坚持下去哦,引用一句我们高三班主任的话:坚持是什么?坚持就是从随时随地的挫折和欲望中摆脱出来,回到原来的路线上为既定的目标而努力奋斗!
好了,话不多说,言归正传。。
1、构造函数有什么特征?
* 函数名称和类名称相同
* 没有返回值
2、构造函数一般可以分为几类?
在我自己的理解中,一般的,我把它大致分为3类:
* 无参构造函数(这种构造函数一般会在自己未显式定义构造函数时,由编译器提供,此时函数体为空,作用仅是为了合乎语法,使编译过程可以通过)
* 一般的有参构造函数(这个一般是我们自定义的构造函数,一般在函数内会做一些基本的包括成员变量在内的一些初始化工作)
* 拷贝构造函数(是个特殊的构造函数,该函数要求形参类型为 const Class& c,作用为当我们使用一个已存在的类对象去初始化一个新的对象时,编译器将自动调用该函数来对新的对象进行相关状态的初始化,最终的效果就是2个对象拥有相同的初始状态)
注:
* 当且仅当,我们提供的类中没有任何构造函数(这里强调:拷贝构造函数也没有哦,因为拷贝构造函数也是构造函数哦)时,编译器在编译的过程当中,会为我们的类自动添加一个函数体为空的无参构造函数,这对应上边的第一种情况
* 当且仅当,我们提供的类中没有任何拷贝构造函数时,编译器在编译过程中,会为我们的类自动添加一个构造函数,作用为进行简单的成员变量的值的复制工作。
3、构造函数何时被调用?
* 只有在我们进行类对象的定义时,编译器才会自动的调用构造函数来对我们的对象状态进行一个初始化,请注意,这里要区分定义和声明的不同。
* 如果我们类的构造函数有多个,必要时,我们也可以手工调用构造函数进行类对象的初始化。
4、深拷贝和浅拷贝
顾名思义
* 深拷贝:就是我们在类的定义时需要向系统申请资源,比如说要使用堆空间、要打开硬盘上的文件等等,就拿申请堆空间来说吧,这个时候在拷贝构造时,就不能只进行成员变量(特别是用来保存申请到的堆空间的那个指针)简单的值的复制了,因为这样可能造成的问题就是拷贝构造之后,2个对象的指针指向了堆空间中的同一片内存空间,那么在我们对象使用完毕需要释放的时候,就可能造成同一片堆空间被delete多次的问题,这会直接导致内存错误,程序运行崩溃,因此此时我们就需要去自定义拷贝构造函数了,在函数中,去在此申请所需的系统资源,从而保证不会出现刚才所说的内存错误。
* 浅拷贝:这就是前边所提到的简单的成员变量的值的复制过程了。
一般的,如果我们需要自定义拷贝构造函数,那么一定是需要进行深拷贝了,因为浅拷贝我们完全可以直接使用编译器给我们提供的默认的拷贝构造函数了,这样就完全没有必要自己再重复定义了。
附一个针对该节相关内容的一个综合例程工参考:
IntArray.h
#pragma once
class IntArray
{
int* _pointer;
int _length;
public:
IntArray(int v);
IntArray(const IntArray& array);
bool setValue(int Pos, int value);
bool getValue(int Pos, int& value);
int getLength();
~IntArray();
};
IntArray.cpp
#include "stdafx.h"
#include "IntArray.h"
IntArray::IntArray(int v)
{
_length = v;
_pointer = new int[_length];
for (int i = 0; i < _length; i++)
{
_pointer[i] = 1;
}
}
IntArray::IntArray(const IntArray& array)
{
_length = array._length;
_pointer = new int[array._length];
for (int i = 0; i < array._length; i++)
{
_pointer[i] = array._pointer[i];
}
}
bool IntArray::setValue(int Pos, int value)
{
bool ret = true;
if ((0 <= Pos) && (Pos < _length))
{
_pointer[Pos] = value;
}
else
{
ret = false;
}
return ret;
}
bool IntArray::getValue(int Pos, int& value)
{
bool ret = true;
if ((0 <= Pos) && (Pos < _length))
{
value = _pointer[Pos];
}
else
{
ret = false;
}
return ret;
}
int IntArray::getLength()
{
return _length;
}
IntArray::~IntArray()
{
delete[] _pointer;
}
main.cpp
#include "stdafx.h"
#include <stdio.h>
#include "IntArray.h"
int main(int argc, char** argv)
{
IntArray intArray(5);
int value = 0;
for (int i = 0; i < intArray.getLength(); i++)
{
intArray.setValue(i, i + 1);
}
for (int i = 0; i < intArray.getLength(); i++)
{
if (intArray.getValue(i, value))
{
printf("value = %d\n", value);
}
}
IntArray intArrayTwo(intArray);
for (int i = 0; i < intArrayTwo.getLength(); i++)
{
if (intArrayTwo.getValue(i, value))
{
printf("value = %d\n", value);
}
}
return 0;
}
至此,关于构造函数的相关基础内容暂时结束,后续有新内容会持续更新。。。