总结:

  默认参数的构造函数,其默认参数必须置于参数列表的结尾。

  设计类的构造函数的时候最好不要同时是用构造函数的重载和带参数的构造函数。

我们可以想象一个这样的场景:某一天书店整理库存,发现了一些非常老的书,为了尽快清空库存,店主想了一下,决定开展一个大甩卖活动,所有的这些书全部以五美元的价格出售。此时如果需要尽快将这些书的信息录入到书店的书单中,为了方便,我们可以在book类中添加一个带默认参数的构造函数。

[例1] 默认带参构造函数示例:

#include<iostream>
using namespace std;

class book
{
public:
    book(){}
    book(char* a, double p = 5.0);
    void display();
private:
    double price;
    char * title;
};

book::book(char* a, double p)  //在定义函数的时候可以不指定默认参数
{
    title = a;
    price = p;
}

void book::display()
{
    cout<<"The price of "<<title<<" is $"<<price<<endl;
}

int main()
{
    book Harry("Harry Potter", 49.9);
    Harry.display();
    book Gone("Gone with the Wind");
    Gone.display();
    return 0;
}

在本例中,book类中的带参构造函数 book(char* a, double p = 5.0); 将价格设置为5.0,如此一来p就被设置成为一个默认参数,如果在创建对象的时候,没有传递实参给该参数p,则该参数会被默认设置为5.0。

在例1的主函数中我们可以看到Harry对象创建时传递了两个实参"Harry potter"和49.9,而Gone 对象则只是传递了一个实参"Gone with the Wind"用于初始化title,此时price就会被用默认参数初始化为5.0。

程序运行结果如下:
The price of Harry Potter is $49.9
The price of Gone with the Wind is $5.0

需要说明的是带默认参数的构造函数,其默认参数必须置于参数列表的结尾。如果例1中带参构造函数 book(char* a, double p = 5.0); 被声明成 book(double p = 5.0, char* a); 则是无法通过编译的,因为默认参数不在参数列表的结尾。

虽然带参数的构造函数会给我们初始化带来一定便利,但糟糕的是它也会给构造函数的调用带来歧义。

[例2] 默认带参构造函数所带来的歧义:

  1. #include<iostream>
  2. using namespace std;
  3. class book
  4. {
  5. public:
  6. book(){}
  7. book(char* a, double p = 5.0);
  8. book(char *a);
  9. void setprice(double a);
  10. double getprice();
  11. void settitle(char* a www.078886.cn);
  12. char * gettitle();
  13. void display();
  14. private:
  15. double price;
  16. char * title;
  17. };
  18. book::book(char* a, double p) //在定义函数的时候可以不指定默认参数
  19. {
  20. title = a;
  21. price = p;
  22. }
  23. book::book(char *a)
  24. {
  25. title = a;
  26. }
  27. void book::display()
  28. {
  29. cout<<"The price of "<<title<<" is $"<<price<<endl;
  30. }
  31. int main()
  32. {
  33. book Harry("Harry potter", 49.9);
  34. Harry.display();
  35. book Gone("Gone with the Wind"); //compile error
  36. Gone.display();
  37. return 0;
  38. }

在本例中有三个构造函数,一个是默认构造函数,两个带参构造函数,其中一个为带有默认参数的构造函数。

在主函数中,通过book类创建Harry对象没有问题,此时创建对象只能调用book(char* a, double p = 5.0);构造函数。创建Gone对象时则有问题了,此时我们创建对象有两个与之匹配的构造函数可以调用,分别是book(char *a);和book(char* a, double p = 5.0);,此时该调用哪一个呢?无法得知,编译器只能报错了。

出现这种情况我们只能极力去避免了,通常而言,在设计类的构造函数的时候最好不要同时是用构造函数的重载和带参数的构造函数,以避免上述问题。

2.9 C++使用默认参数的构造函数的更多相关文章

  1. C++使用默认参数的构造函数

    我们可以想象一个这样的场景:某一天书店整理库存,发现了一些非常老的书,为了尽快清空库存,店主想了一下,决定开展一个大甩卖活动,所有的这些书全部以五美元的价格出售.此时如果需要尽快将这些书的信息录入到书 ...

  2. C++:构造函数的默认参数知识拓展

    和普通函数一样,构造函数中参数的值既可以通过实参传递,也可以指定为某些默认值,即如果用户不指定实参值,编译系统就使形参取默认值.   例9.3的问题也可以使用包含默认参数的构造函数来处理.   [例9 ...

  3. C++中关于重载默认构造函数与默认全部参数的构造函数的使用注意

    # include<iostream>using namespace std;class Time{public:                            //公用成员函数  ...

  4. C++构造函数重载以及默认参数引起的二义性

    大家都知道当我们声明一个类时,系统会提供一个默认构造函数.当我们需要提供参数进行对类数据成员进行初始化时,就需要对类的带参构造函数进行重载.同时,如果我们需要调用默认构造函数进行类数据成员的初始化时, ...

  5. c++默认参数函数注意事项

    再有默认参数的函数中,一般我们都把默认参数放在声明处而不是定义处. 如果声明和定义都有默认参数,编译器将会报错. 调用含有默认实参的函数时,我们可以包含参数,也可以省略. 有默认参数的函数,我们可以不 ...

  6. C++构造函数的自动调用(调用一个父类的构造函数,有显性调用最好,否则就默认调用无参数的构造函数)——哲学思想:不调用怎么初始化父类的成员数据和VMT?

    我总是记不住构造函数的特点,关键还是没有领会那个哲学思想:父类的构造函数一方面要初始化它自己的成员数据,另一方面也要建立它自己的VMT呀!心里默念一百遍:一定调用父类构造函数,一定调用父类构造函数,一 ...

  7. C#深入学习笔记 - 可空类型与构造函数默认参数

    在实际开发中或许可能会遇到某个属性需要提供一个默认参数,如果该参数是引用类型的话,可以通过 使用 null 来表示未知的值,但如果是int或 其他值类型的话就有点不好办了,因为如果需要一个int或fl ...

  8. [c++] 子类构造函数中有默认参数

    子类创建对象时调用父类的构造函数: 1 #include <iostream> 2 using namespace std; 3 class Base 4 { 5 public: 6 Ba ...

  9. 拷贝构造函数,深拷贝,大约delete和default相关业务,explicit,给定初始类,构造函数和析构函数,成员函数和内联函数,关于记忆储存,默认参数,静态功能和正常功能,const功能,朋友

     1.拷贝构造 //拷贝构造的规则,有两种方式实现初始化. //1.一个是通过在后面:a(x),b(y)的方式实现初始化. //2.另外一种初始化的方式是直接在构造方法里面实现初始化. 案比例如以 ...

随机推荐

  1. 01-Mirrorgate简介

    1.项目信息 MirrorGate是一款WallBoard应用程序,旨在为团队提供与软件开发相关的所有不同领域的快速反馈.       项目地址:https://github.com/BBVA/mir ...

  2. Matplotlib 简单图例

    图例参考:http://matplotlib.org/gallery.html API参考:http://matplotlib.org/api/pyplot_summary.html # -*- co ...

  3. Vue-嵌套路由

    一个被渲染组件同样可以包含自己的嵌套 <router-view>.同样要有vue-router的三个要素:路由map .路由视图.路由导航. 举个在"/apple" 下 ...

  4. Java 面试题 == 和 equals 的区别

    int和Integer的区别 1.Integer是int的包装类,int则是java的一种基本数据类型 2.Integer变量必须实例化后才能使用,而int变量不需要 3.Integer实际是对象的引 ...

  5. 如何使用串口来给STM32下载程序

    前言 第一次学习STM32的时候,不知道有调试器这个东西,所以一直是通过串口来给STM32下载程序,下载速度也还算可以,一般是几秒钟完成.后来用了调试器,可以直接在Keil环境下进行下载,而且还可以进 ...

  6. python第二周

    第二周,PYTHON图形绘制 一,计算机技术的演进发展 1946-1981.从第一台计算机的诞生到IBM的PC机的出现,我们称之为”计算机系统结构时代“.————这个时代重点在解决计算能力问题 198 ...

  7. LESS SCSS 预编译语言

      前  言 JRedu LESS  是一门 CSS 预处理语言,它扩展了 CSS 语言,增加了变量.Mixin.函数等特性,使 CSS 更易维护和扩展. LESS 为 Web 开发者带来了福音,它在 ...

  8. CentOS7下安装Docker-Compose操作记录

    Docker-Compose是一个部署多个容器的简单但是非常必要的工具.安装Docker-Compose之前,请先安装 python-pip 一.安装 python-pip [root@workben ...

  9. ubuntu系统升级和其他相关操作记录

    之前在openstack中安装了ubuntu 12.04虚拟机,版本较低,需要升级为高版本.下面分享下升级过程: ubuntu系统升级操作:$ cat /etc/issueUbuntu 12.04.5 ...

  10. Python_初识函数和返回值_22

    #len s = '金老板小护士' len(s) def my_len(): #自定义函数 i = 0 for k in s: i += 1 print(i) length = my_len() pr ...