>[info]# **构造函数的需要性**
* 需要有一个专门的函数完成对象的初始化工作,由于类的封装性,该工作自然落在类的**成员函数**(构造函数)身上.
* 以**类名作为函数名的函数**称为类的构造函数(C++标准中认为**构造函数是无名函数**,原因是类型名不能作为函数名.这里为了便于理解,将类名称为构造函数的函数名).
* **声明构造函数原型**的一般形式: 类名(形参列表);
* **定义构造函数**的一般形式:
~~~
类名::类名(形参列表)<:成员初始化列表> //多用于继承和聚集类
{
语句序列
}
~~~
>[info]# **构造函数作用**
* 知道编译器为当前命名的对象分配命名空间
* 独立完成当前类中数据成员的初始化工作
## **例子**
~~~
#include <iostream>
using namespace std;
class Time
{
public:
Time( ) //定义构造成员函数,函数名与类名相同
{
hour=0; //利用构造函数对对象中的数据成员赋初值
minute=0;
sec=0;
}
void set_time( ); //公有成员函数声明
void show_time( ); //公有成员函数声明
private:
int hour; //私有数据成员
int minute;
int sec;
};
void Time∷set_time( ) //定义成员函数,向数据成员赋值
{
cin>>hour;
cin>>minute;
cin>>sec;
}
void Time∷show_time( ) //定义成员函数,输出数据成员的值
{
cout<<hour<<″:″<<minute
<<″:″<<sec<<endl;
}
int main( )
{
Time t1; //建立对象t1,同时调用构造函数t1.Time( )
t1.set_time( ); //对t1的数据成员赋值
t1.show_time( ); //显示t1的数据成员的值
Time t2; //建立对象t2,同时调用构造函数t2.Time( )
t2.show_time( ); //显示t2的数据成员的值
return 0;
}
~~~
构造函数也可以在类外定义
~~~
/*在类内进行声明
在类外定义 */
Time::Time() //一定要加上类名Time和域限定符::
{
hour=0;
minute=0;
sec=0;
}
~~~
>[info]# **带参的构造函数**
可以采用带参的构造函数,在调用不同的对象的构造函数时,从外面将不同的数据赋给构造函数,以实现不同的初始化。
定义带参构造函数的格式:
~~~
构造函数名(类型1,类型2...)
~~~
定义对象时格式:
~~~
类名 对象名(实参1,实参2...);
~~~
## **例子**
~~~
#include <iostream>
using namespace std;
class Box
{
public:
Box(int,int,int); //声明带参数的构造函数
int volume( ); //声明计算体积的函数
private:
int height;
int width;
int length;
};
Box∷Box(int h,int w,int len) //在类外定义带参数的构造函数
{
height=h;
width=w;
length=len;
}
int Box∷volume( ) //定义计算体积的函数
{
return(height*width*length);
}
int main( )
{
Box box1(12,25,30); //建立对象box1,并指定box1长,宽,高的值
cout<<″The volume of box1 is ″
<<box1.volume( )<<endl;
Box box2(15,30,21); //建立对象box2,并指定box2长,宽,高的值
cout<<″The volume of box2 is ″
<<box2.volume( )<<endl;
return 0;
}
~~~
~~~
/* 用参数初始化列表对数据成员初始化 */
#include <iostream>
#include <cstring>
using namespace std;
class Student
{
public:
Student(char* pName)
{
cout <<"constructing student " <<pName //带参构造函数或称有参构造函数
<<endl;
strcpy(name,pName);
name[sizeof(name)-1]='\0'; //name[19]='\0'
}
~Student() //析构函数
{
cout <<"destructing " <<name <<endl;
}//其他公共成员
protected:
char name[20];
};
int main()
{
Student ss("Jenny"); /* 调用有参构造函数进行对象的初始化,此句还可写成:Student ss="Jenny";
类似的,在ISO C++标准14882中,int a=10;与int a(10);等价.(赋值时只有 一种形式,即int a=10) */
return 0;
}
~~~
~~~
/* 带多个参数的有参构造函数. */
#include <iostream>
#include <cstring>
class Student{
public:
Student(char* pName, int xHours, float xgpa)
{
cout <<"constructing student "
<<pName <<endl;
strncpy(name,pName,sizeof(name));
name[sizeof(name)-1]='\0';
semesHours=xHours;
gpa=xgpa;
}
~Student() //析构函数
{
cout <<"destructing " <<name <<endl;
}//其他公共成员
protected:
char name[20];
int semesHours;
float gpa;
};
int main()
{
Student ss("Jenny",22,3.5);
return 0;
}
~~~
=
~~~
/* 构造函数的重载 */
#include <iostream>
using namespace std;
class Tdate
{
public:
Tdate(); //无参构造函数 称为默认构造函数
Tdate(int d);
Tdate(int m,int d);
Tdate(int m,int d,int y); //4个构造函数 其他公共成员
protected:
int month;
int day;
int year;
};
Tdate::Tdate()
{
month=4;
day=15;
year=1995;
cout <<month <<"/" <<day <<"/" <<year <<endl;
}
Tdate::Tdate(int d)
{
month=4;
day=d;
year=1996;
cout <<month <<"/" <<day <<"/" <<year <<endl;
}
Tdate::Tdate(int m,int d)
{
month=m;
day=d;
year=1997;
cout <<month <<"/" <<day <<"/" <<year <<endl;
}
Tdate::Tdate(int m,int d,int y)
{
month=m;
day=d;
year=y;
cout <<month <<"/" <<day <<"/" <<year <<endl;
}
int main()
{
Tdate aday; //此处不能写成Tdate aday();
//因为c++编译器会理解为一个无参函数aday的声明,该函数返回Tdate类对象.
Tdate bday(10);
Tdate cday(2,12);
Tdate dday(1,2,1998);
return 0;
}
~~~
~~~
/* 定义两个构造函数,其中一个无参数,一个有参数. */
#include <iostream>
using namespace std;
class Box
{
public:
Box( ); //声明一个无参的构造函数
Box(int h,int w,int len) \
:height(h),width(w),length(len){ } //声明一个有参的构造函数,用参数的初始化表
//对数据成员初始化
int volume( );
private:
int height;
int width;
int length;
};
Box∷Box( ) //定义一个无参的构造函数
{
height=10;
width=10;
length=10;
}
int Box∷volume( )
{
return(height*width*length);
}
int main( )
{
Box box1; //建立对象box1,不指定实参
cout<<″The volume of box1 is ″<<box1.volume( )<<endl;
Box box2(15,30,25); //建立对象box2,指定3个实参
cout<<″The volume of box2 is ″<<box2.volume( )<<endl;
return 0;
}
~~~
**“\\”的作用**:
* 普通的\\
* 转义字符
* 续行,上下两行属于同一行语句. ' \ '后不能写任何东西
~~~
/* 默认构造函数(缺省构造函数) */
#include <iostream>
#include <cstring>
using namespace std;
class Student
{
public:
Student(char* pName)
{
strncpy(name,pName,sizeof(name));
name[sizeof(name)-1]='\0';
}
Student(){}
protected:
char name[20];
};
int main()
{
Student noName; //ok 调用无参构造函数
Student ss("Jenny"); //ok 调用有参构造函数
return 0;
}
/* 若要创建无参对象,即使在类中已有有
参构造函数的情况下,也要增加一个无
参构造函数,否则编译出错.
*/
~~~
>[info]# **规定**
* 构造函数的**调用时机**对理解C++程序的执行过程非常重要。
* c+规定,在创建一个对象时,构造函数被系统**自动调用**。这就意味着当执行一个对象声明语句或者用操作符new动态创建对象时,都会导致自动调用执行构造函数除此之外,在程序中不能直接调用构造函数,因为c++标准中认为构造函数是无名函数,而无名函数对于程序正文而言是不可见的.
<br>
## **c++规定:**
* 不能为构造函数指定任何返回类型,即使void也不行
* 构造函数允许带参,因此构造函数可以重载。构造函数可以分为无参和有参构造函数。无参构造函数又称为**缺省构造函数**或**默认构造函数**
* 如果**没有为一个类定义任何构造函数**时,编译器会为该类**自动产生**一个隐含声明的**缺省构造函数**。隐含声明的缺省构造函数什么都不做
* 构造函数可以是类的**public**的或者**protected**的成员函数,当构造函数为**protected**的构造函数时,意味着除自身之外只有其**派生类**和**友员**能够创建该类的对象。
- 介绍
- 编程设计语言
- 第一章 对C++的初步认识
- 1.2 最简单的C++程序
- 1.3 C++对C的补充
- 1.3.1 return
- 1.3.2 输入输出流
- 1.3.3 putchar 和 getchar
- 1.3.4 用const定义常变量
- 1.3.5 函数原型声明
- 1.3.6 内置函数
- 1.3.7 函数重载
- 1.3.8 函数模板
- 1.3.9 有默认值的参数
- 1.3.10 作用域
- 1.3.11 const修饰指针
- 1.3.12 引用
- 1.3.13 生命期
- 1.3.14 变量
- 1.3.15 字符串变量
- 第二章 类与对象
- 2.2 类的声明和对象的定义
- 2.3 类的成员函数
- 第三章 关于类和对象的进一步讨论
- 3.1 构造函数
- 3.1.1 对象的初始化
- 3.1.2 构造函数
- 3.2 析构函数
- 3.3调用析构函数和构造函数的顺序
- 3.4 对象数组
- 3.5 对象指针
- 3.6 共享数据的保护
- 3.7 对象的建立与释放
- 3.8 对象的赋值与复制
- 3.9 静态成员
- 3.10 友元
- 3.11 类模板
- 第四章 运算符重载
- 数据类型转换
- 运算符重载
- 重载流插入运算符和流提取运算符
- 第五章 继承与派生
- 继承与派生
- 第六章 多态性与虚函数
- 多态性
- 虚函数
- 纯虚函数与抽象类