1、构造函数
构造函数和普通函数的区别:普通函数的函数名可以随机定义,而构造函数的函数名和类名一致;普通函数有返回值,而构造函数没有返回值;普通函数可以定义参数,那么构造函数可以定义参数吗?
- 带参数的构造函数
— 构造函数可以根据需要定义参数
— 一个类中可以存在多个重载的构造函数
— 构造函数的重载遵循C++ 重载的规则
class Test
{
public:
Test(int v)
{
//use v to initialize member
}
};
- 友情提醒
— 对象定义和对象声明不同
1、对象定义:申请对象的空间并调用构造函数
2、对象声明:告诉编译器存在这样一个对象,对象在哪里不知道,链接的时候会去找
Test t; //定义对象并调用构造函数
int main()
{
//告诉编译器存在名为 t 的Test对象
extern Test t;
return 0;
}
我们的整个编译过程分为好几步:
1、预处理
2、编译器出场,对我们的源代码进行语法检查并生成目标文件
3、链接器出场,链接器就会去找我们目标文件里面存在的一些名字,比如它会发现上面的程序有一个没有解决的名字 t ,链接器就会去各个目标文件寻找 t 究竟是在哪里定义的。
对象的初始化自动会调用构造函数,而给对象赋值不会调用构造函数。我们初始化的写法一般有两种
int i = 100;
int i(100);
引申到对象的初始化,下面这三种初始化方式,都是对象的初始化。
Test t1 = 3;
Test t2(3);
Test t = Test(100);
- 构造函数的自动调用
程序:带参数的构造函数
#include <stdio.h>
class Test
{
public:
Test()
{
printf("Test()\n");
}
Test(int v)
{
printf("Test(int v),v = %d\n",v);
}
};
int main()
{
Test t1; //调用Test()
Test t2(1); //调用Test(int v)
Test t3 = 2; //调用Test(int v)
return 0;
}
- 构造函数的调用
— 一般情况下,构造函数在对象定义时被自动调用
— 一些特殊情况,需要手工调用构造函数
如何创建一个对象数组?
#include <stdio.h>
class Test
{
private:
int m_value;
public:
Test()
{
m_value = 0;
printf("Test()\n");
}
Test(int v)
{
m_value = v;
printf("Test(int v),v = %d\n",v);
}
int getValue()
{
return m_value;
}
};
int main()
{
Test ta[3] = { Test(),Test(1),Test(2) }; //对象数组的初始化,手工调用构造函数
for (int i = 0; i < 3; i++)
{
printf("ta[%d].m_value = %d\n", i, ta[i].getValue());
}
Test t1 = Test(100); //新的初始化方式
printf("t1.m_value = %d\n", t1.getValue());
return 0;
}
手工调用构造函数可以让我们的对象数组里面每个成员的初始化都是我们想要的值。
2、小实例
- 需求:开发一个数组类解决原生数组的安全性问题
— 提供函数获取数组的长度
— 提供函数获取数组元素
— 提供函数设置数组元素
IntArray.h:
#ifndef _IntArray_H_
#define _IntArray_H_
#pragma once
class IntArray
{
private:
int m_length;
int* m_pointer;
public:
IntArray(int len);
int length();
bool set(int index, int value);
bool get(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::set(int index, int value)
{
bool ret = ((0 <= index) && (index < m_length));
if (ret)
{
m_pointer[index] = value;
}
return ret;
}
bool IntArray::get(int index, int& value)
{
bool ret = ((0 <= index) && (index < m_length));
if (ret)
{
value = m_pointer[index];
}
return ret;
}
void IntArray::free()
{
delete[]m_pointer;
}
main.cpp
#include <stdio.h>
#include "IntArray.h"
int main()
{
IntArray a(5);
for (int i = 0; i < a.length(); i++)
{
a.set(i, i + 1);
}
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++中重载函数的规则
- 对象定义时会触发构造函数的调用
- 在一些情况下可以手动调用构造函数