| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2099 人关注过本帖
标题:定义构造函数的四种方法
只看楼主 加入收藏
lyb661
Rank: 5Rank: 5
等 级:贵宾
威 望:18
帖 子:47
专家分:83
注 册:2018-12-12
结帖率:71.43%
收藏
 问题点数:0 回复次数:0 
定义构造函数的四种方法
定义构造函数的四种方法

作者:lyb661

  定义类的构造函数有如下几种方法:
  1、使用默认构造函数(类不另行定义构造函数):能够创建一个类对象,但不能初始化类的各个成员。
  2、显式定义带有参数的构造函数:在类方法中定义,使用多个参数初始化类的各个数据成员。
  3、定义有默认值的构造函数:构造函数原型中为类的各个成员提供默认值。
  4、使用构造函数初始化列表:这个构造函数初始化成员的方式显得更紧凑。
例如:有一个学生类。其中存储了学生的姓名、学号和分数。
class Student
{
 private:
  std::string name;
  long number;
  double scores;
public:
  Student(){}//1:default constructor
  Student(const std::string& na,long nu,double sc);
  Student(const std:;string& na="",long nu=0,double sc=0.0);
  Student(const std:;string& na="none",long nu=0,double sc=0.0):name(na),number(nu),scores(sc){}
  ………..
  void display() const;
  //void set(std::string na,long nu,double sc);
};
.........
Student::Student(const std::string& na,long nu,double sc)
{
  name=na;
  number=nu;
  scores=sc;
}
void Student::display()const
{
  std::cout<<"Name: "<<name<<", Number: "<<number<<", Score: "<<scores<<"\n\n";
}
  这个学生类极为简单:除了创建和显示学生的姓名、学号、学分以外;什么工作也不做,什么工作也做不了。
  这个类在此处的价值的就是说明类构造函数的工作方式。
1、第一个构造函数,就是编译器合成的默认构造函数。它用于创建一个类对象而不显式地初始化各个类成员。
  Student(){}
................
   Student st1;
  这里创建一个学生类的对象st1。但对st1的姓甚名谁、学号大小、学分多少一无所知。
  对于一个简单的类:我们无需显式地定义这个构造函数,因为编译器会隐式地调用它来创建类对象。为了创建一个具体的类对象,有时可定义一个私有成员函数来初始化类的各个成员。
比如Set_name(string) , Set_score(double)…..
2、第二个构造函数带有三个参数:分别对应于三个类成员。经过类方法中的定义,我们可以在用户程序中创建一个各个成员赋有初值的类对象。
  Student(const string& na,long nu,double sc);
................
  Student st2("LiuYang",0803,96.5);
  这里创建了一个学生类st2。他的姓名、学号、学分分别为LiuYang , 0803 , 96.5。
  值得注意的是:由于我们显式地定义了一个带有参数的构造函数,编译器合成的默认构造函数将不再工作。因此,在用户程序中声明一个没有成员值的学生类对象就不允许了。即下面的代码是非法的!
  Student st2;
3、对于第二个构造函数的问题,我们有两种方法来解决:一是同时显式地调用默认的构造函数。即第1 第 2个构造函数同时调用。这样既可创建一个类对象,也能对其进行初始化。
  另一个办法是定义一个参数带有默认值的构造函数。它兼有第1 第 2个构造函数的功能。即创建一个类对象,同时为它赋初值。
  Student(const std::string& na="none,long nu=0,double sc=0.0);
................
  Student st3;//实际上st3也是有默认值的了
  st3=Student("LiMing",0705,88.3);
  Student st3("LiMing",0705,88.3); //同理
  在所有类型的构造函数中,带有默认值的构造函数最为实用,也最为简洁。
4、正因为此,构造函数初始化列表的应用才被广泛地应用。
  Student(const std:;string& na="none",long nu=0,double sc=0.0):name(na),number(nu),scores(sc){}
  不但因为它是带有默认参数的构造函数,也因为它初始化成员的方式最为直观,最为简洁。
  这使构造函数也好像被封装在类声明里了。尽管构造函数初始化列表看起来简单,其实也能完成复杂的初始化工作。
  例如有一个商品类:
   class ShangPin
{
    std::string PM;//品名
    long SL;//数量
    double DJ;//单价
    double JE;//金额
…!…
};
其成员有品名、数量、单价、金额。显然金额的初始化不是直接完成的,只有数量和单价已知后它才能确定。尽管工作有点麻烦,但初始化列表也能胜任。
  可以在大括号中,调用一个私有的函数来完成金额的初始化工作。
  ShangPin(const std::string& m_PM="nothing",long m_SL=0,double m_DJ=0.0):PM(m_PM),SL(m_SL),DJ(m_DJ){set_JE();}
................
  void ShangPin::set_JE()
  {
    JE=SL*DJ;
  }
  类成员的初始化工作是十分重要的。有时我们编写好的程序,在运行时会输出些莫名其妙的乱码,这可能与我们初始化工作做不到位有关。
  根据程序对类的需求,我们应该更清晰地选择构造函数的编写方法。对于一般的类,构造函数初始化列表通常是最好的选择。
  当然,我们必须必须熟悉各种构造函数的工作方式,才能作出最恰如其分的选择。
搜索更多相关主题的帖子: 定义 构造函数 初始化 成员 Student 
2019-04-10 08:47
快速回复:定义构造函数的四种方法
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.015946 second(s), 10 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved