C++构造函数—构造函数的声明与定义、带参数的构造函数

构造函数是一种随着对象创建而自动被调用的函数,它的主要用途是为对象作初始化。那么,构造函数到底是什么样子的呢?

构造函数的声明与定义

在C++中,规定与类同名的成员函数就是构造函数。 需要注意的是,构造函数应该是一个公有的成员函数,并且构造函数没有返回值类型。以下是我们为链表结点类编写的一个构造函数:(其他成员函数定义见14.3节)
//node.h
#include //如果不包含iostream头文件,这个文件里就不能用cout
using namespace std;
class Node//定义一个链表结点类
{
   public:
   ……
   Node();//构造函数的声明,构造函数是公有的成员函数,没有返回值类型
   ……
   private:
   int idata;//存储数据保密
   char cdata;//存储数据保密
   Node *prior;//前驱结点的存储位置保密
   Node *next;//后继结点的存储位置保密
};

Node::Node()//构造函数的定义
{
   cout <<"Node constructor is running..." <    idata=0;//初始化idata
   cdata='0';//初始化cdata
   prior=NULL;//初始化前驱结点指针
   next=NULL;//初始化后续结点指针
}

这时,我们创建一个链表结点对象,构造函数随着对象创建而自动被调用,所以这个对象创建之后idata的值为0,cdata的值为'0',prior和next的值都是NULL:(程序15.2.1)
//main.cpp
#include
#include "node.h"
using namespace std;
int main()
{
   Node a;//创建一个链表结点对象a,调用构造函数
   cout <    cout <    return 0;
}

运行结果:
Node constructor is running...
0
0
可是,这样的构造函数还是不太理想。如果每次初始化的值都是固定的,那么有没有构造函数都是一样的。构造函数变成了一种摆设!我们该怎么办?

带参数的构造函数

函数的特征之一就是能够在调用时带上参数。既然构造函数也是函数,那么我们就能给构造函数带上参数,使用重载或默认参数等方法,从而实现更自由地对对象进行初始化操作。以下便是对链表结点类的进一步修改:(程序15.2.2)
//node.h
#include
using namespace std;
class Node//定义一个链表结点类
{
   public:
   Node();//构造函数0
   Node(int i,char c='0');//构造函数重载1,参数c默认为'0'
   Node(int i,char c,Node *p,Node *n);//构造函数重载2
   int readi() const;//读取idata
   char readc() const;//读取cdata
   Node * readp() const;//读取上一个结点的位置
   Node * readn() const;//读取下一个结点的位置
   bool set(int i);//重载,通过该函数修改idata
   bool set(char c);//重载,通过该函数修改cdata
   bool setp(Node *p);//通过该函数设置前驱结点
   bool setn(Node *n);//通过该函数设置后继结点
   private:
   int idata;//存储数据保密
   char cdata;//存储数据保密
   Node *prior;//前驱结点的存储位置保密
   Node *next;//后继结点的存储位置保密
};
int Node::readi() const//成员函数readi的定义
{
   return idata;
}

char Node::readc() const
{
   return cdata;
}
Node * Node::readp() const
{
   return prior;
}
Node * Node::readn() const
{
   return next;
}
bool Node::set(int i)//重载成员函数定义
{
   idata=i;
   return true;
}
bool Node::set(char c)
{
   cdata=c;
   return true;
}
bool Node::setp(Node *p)
{
   prior=p;
   return true;
}
bool Node::setn(Node *n)
{
   next=n;
   return true;
}
Node::Node()//构造函数0的定义
{
   cout <<"Node constructor is running..." <    idata=0;//初始化idata
   cdata='0';//初始化cdata
   prior=NULL;//初始化前驱结点指针
   next=NULL;//初始化后续结点指针
}
Node::Node(int i,char c)//构造函数重载1,默认参数只需要在函数原型中出现
{
   cout <<"Node constructor is running..." <    idata=i;
   cdata=c;
   prior=NULL;
   next=NULL;
}
Node::Node(int i,char c,Node *p,Node *n)//构造函数重载2
{
   cout <<"Node constructor is running..." <    idata=i;
   cdata=c;
   prior=p;
   next=n;
}
//main.cpp
#include
#include "node.h"
using namespace std;
int main()
{
   Node a;//创建一个链表结点对象a,调用构造函数0
   Node b(8);//创建一个链表结点对象b,调用构造函数重载1,参数c默认为'0'
   Node c(8,'F',NULL,NULL);//创建一个链表结点对象c,调用构造函数重载2
   cout <    cout <    cout <    return 0;
}

运行结果:
Node constructor is running...
Node constructor is running...
Node constructor is running...
0 0
8 0
8 F

我们看到,在参数和重载的帮助下,我们可以设计出适合各种场合的构造函数。初始化各个对象的成员数据对我们来说已经是小菜一碟了。但是,这时你是否会回想起当初没有编写构造函数时的情形?如果没有编写构造函数,对象的创建是一个怎样的过程呢?

在C++中,每个类都有且必须有构造函数。如果用户没有自行编写构造函数,则C++自动提供一个无参数的构造函数,称为默认构造函数。这个默认构造函数不做任何初始化工作。一旦用户编写了构造函数,则这个无参数的默认构造函数就消失了。如果用户还希望能有一个无参数的构造函数,必须自行编写。


原文:http://see.xidian.edu.cn/cpp/biancheng/view/81.html

你可能感兴趣的:(c/c++)