2025年4月26日 星期六 乙巳(蛇)年 正月廿七 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > VC/VC++

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

时间:01-10来源:作者:点击数:95

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

构造函数的声明与定义

在C++中,规定与类同名的成员函数就是构造函数。需要注意的是,构造函数应该是一个公有的成员函数,并且构造函数没有返回值类型。以下是我们为链表结点类编写的一个构造函数:(其他成员函数定义见14.3节)

//node.h

  • #include <iostream>//如果不包含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..." <<endl;//提示构造函数运行
  • idata=0;//初始化idata
  • cdata='0';//初始化cdata
  • prior=NULL;//初始化前驱结点指针
  • next=NULL;//初始化后续结点指针
  • }

这时,我们创建一个链表结点对象,构造函数随着对象创建而自动被调用,所以这个对象创建之后idata的值为0,cdata的值为'0',prior和next的值都是NULL:(程序15.2.1)

//main.cpp

  • #include <iostream>
  • #include "node.h"
  • using namespace std;
  • int main()
  • {
  • Node a;//创建一个链表结点对象a,调用构造函数
  • cout <<a.readi() <<endl;
  • cout <<a.readc() <<endl;
  • return 0;
  • }

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

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

带参数的构造函数

函数的特征之一就是能够在调用时带上参数。既然构造函数也是函数,那么我们就能给构造函数带上参数,使用重载或默认参数等方法,从而实现更自由地对对象进行初始化操作。以下便是对链表结点类的进一步修改:(程序15.2.2)

//node.h

  • #include <iostream>
  • 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..." <<endl;//提示构造函数运行
  • idata=0;//初始化idata
  • cdata='0';//初始化cdata
  • prior=NULL;//初始化前驱结点指针
  • next=NULL;//初始化后续结点指针
  • }
  • Node::Node(int i,char c)//构造函数重载1,默认参数只需要在函数原型中出现
  • {
  • cout <<"Node constructor is running..." <<endl;
  • idata=i;
  • cdata=c;
  • prior=NULL;
  • next=NULL;
  • }
  • Node::Node(int i,char c,Node *p,Node *n)//构造函数重载2
  • {
  • cout <<"Node constructor is running..." <<endl;
  • idata=i;
  • cdata=c;
  • prior=p;
  • next=n;
  • }

//main.cpp

  • #include <iostream>
  • #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 <<a.readi() <<' ' <<a.readc() <<endl;
  • cout <<b.readi() <<' ' <<b.readc() <<endl;
  • cout <<c.readi() <<' ' <<c.readc() <<endl;
  • return 0;
  • }

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

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

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

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门