C++深度解析 对象的构造(中)---对象定义和声明,构造函数的重载,手工和自动调用构造函数,数组类(17)
对象的构造由构造函数完成
函数名与类名相同,并且不能有任何返回值。
带有参数的构造函数
意义:可以使得每个对象有不同的初始化状态。
一个类中可以存在多个重载的构造函数。
构造函数的重载遵循C++重载的规则。
对象定义和对象声明不同
对象定义:申请对象的空间并调用构造函数
对象声明:告诉编译器存在这样一个对象
Test t; //定义对象并调用构造函数
int main()
{
//告诉编译器存在名为t的Test对象
extern Test t;
return 0;
}
分析:通过链接时找到对象定义的地方。编译过程:预处理,编译器出厂(对源代码进行语法检查,生成目标文件),链接器出厂。
定义对象时,构造函数的自动调用。构造函数可以重载
实例程序:(带参数的构造函数)
#include <stdio.h>
class Test
{
public:
Test()
{
printf("Test() \n");
}
Test(int v)
{
printf("Test(int v), v = %d\n", v);
}
};
int main()
{
Test t; //调用 Test()
Test t1(1); //调用 Test(int v)
Test t2 = 2; //调用 Test(int v),使用2初始化t2
//int i;//初始化,i的初始值是随机的
//i = 1;//赋值,不是初始化
//初始化和赋值不同,初始化是会调用构造函数,赋值则不会
//t = t2;//赋值操作
//初始化和赋值是不同的
int i(100); //初始化
printf("i = %d\n", i);
return 0;
}
结果如下:
手工调用构造函数
示例程序:
#include <stdio.h>
class Test
{
private:
int m_value;
public:
Test()
{
printf("Test() \n");
m_value = 0;
}
Test(int v)
{
printf("Test(int v), v = %d\n", v);
m_value = v;
}
int getValue()
{
return m_value;
}
};
int main()
{
//对象数组
//Test ta[3]; //数组里面的3个对象调用构造函数Test()
//对象数组
Test ta[3] = {Test(), Test(1), Test(2)};//手工调用构造函数
for(int i = 0; i < 3; i++)
{
printf("ta[%d].getValue() = %d\n", i, ta[i].getValue());
}
//手工调用构造函数
Test t = Test(100);
printf("t.getValue() = %d\n", t.getValue());
return 0;
}
结果如下:
小实例
需求:开发一个数组类解决原生数组的安全性问题
-
提供函数获取数组长度
-
提供函数获取数组元素
-
提供函数设置数组元素
实例程序:(数组类的实现)
IntArray.h(声明数组类)
#ifndef _INTARRAY_H_
#define _INTARRAY_H_
//数组类的声明
class IntArray
{
private:
int m_length; //长度
int* m_pointer; //数据
public:
IntArray(int len);
int length(); //得到数组的长度
bool get(int index, int& value); //得到对应位置的数组元素值
bool set(int index, int value); //设置对应位置的数组元素值
void free(); //释放对应的堆空间
};
#endif
IntArray.cpp(实现数组类)
#include "IntArray.h"
//构造函数
IntArray::IntArray(int len)
{
//数据指针指向堆空间一段内存
m_pointer = new int[len];
for(int i = 0; i < len; i++)
{
m_pointer[i] = 0;
}
m_length = len;
}
int IntArray::length()
{
return m_length;
}
bool IntArray::get(int index, int& value)
{
//确保index在合法的位置,没有越界
bool ret= (0 <= index) && (index < length());
if(ret)
{
//通过引用返回一个值
value = m_pointer[index];
}
return ret;
}
bool IntArray::set(int index, int value)
{
//确保index在合法的位置,没有越界
bool ret = (0 <= index) && (index < length());
if(ret)
{
//数组的成员重新赋值
m_pointer[index] = value;
}
return ret;
}
void IntArray::free()
{
//释放对应的堆空间
delete[] m_pointer;
}
test.cpp
#include <stdio.h>
#include "IntArray.h"
int main()
{
//定义一个数组类IntArray对象a,元素个数为5
IntArray a(5);
for(int i = 0; i < a.length(); i++)
{
a.set(i, i + 1); //1~5
}
for(int i = 0; i < a.length(); i++)
{
int value = 0;
if(a.get(i, value))
{
printf("a[%d] = %d\n", i, value);
}
}
//释放对应的堆空间
a.free();
return 0;
}
结果如下:
小结
构造函数可以根据需要定义参数
构造函数之间可以存在重载关系
构造函数遵循C++中重载函数的规则
对象定义时会触发构造函数的调用
在一些情况下可以手动调用构造函数