在代码中使用到了函数的默认参数,在函数的定义和实现中都填写的默认参数,结果出现了错误:

代码:

 #ifndef FIRSTPAGE_H
#define FIRSTPAGE_H #include <QWizardPage>
#include "ui_firstdialog.h" class FirstPage : public Ui::FirstDialog, public QWizardPage
{
public:
FirstPage(QWidget *parent = );
}; #endif // FIRSTPAGE_H
 #include "fifthpage.h"

 FifthPage::FifthPage(QWidget *parent = ) :
QWizardPage(parent)
{
}

当去掉了实现文件中的默认参数值时,通过了编译,于是就考虑是不是因为同时在定义文件中和实现文件中都填写了默认参数造成了这个错误。在网上搜到一篇讲的比较详细的文章: 函数声明和函数定义中的默认参数浅析

默认参数是存在于函数的声明中,还是函数的定义中呢?

    我在VS6.0和VS2008下做了如下实验,并做出了简单的总结,有不足或者不准确的地方,欢迎大家拍砖,我会及时修正相关内容。
 
    实验一:默认参数不能同时存在于函数声明和函数定义中
 
  1. #include <iostream>
  2. #include <tchar.h>
  3. using namespace std;
  4. void SetHeight(double dHeight = 183.5);
  5. int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
  6. {
  7. SetHeight(181.5);
  8. return 1;
  9. }
  10. void SetHeight(double dHeight = 183.5)
  11. {
  12. cout << _T("身高为:") << dHeight << endl;
  13. }
然后调整一下顺序(本文的例子只用于实验,并不侧重于代码本身是否有意义):
 
  1. #include <iostream>
  2. #include <tchar.h>
  3. using namespace std;
  4. void SetHeight(double dHeight = 183.5);
  5. void SetHeight(double dHeight = 183.5)
  6. {
  7. cout << _T("身高为:") << dHeight << endl;
  8. }
  9. int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
  10. {
  11. SetHeight(181.5);
  12. return 1;
  13. }
两处代码编译的时候,编译器都会报告如下错误:
error C2572: 'SetHeight' : redefinition of default parameter : parameter 1,see declaration of 'SetHeight'
 
实验一小结:编译器不允许默认参数同时存在于声明和定义中,之所以这个做,个人猜测:
1、没必要,声明和定义都有默认参数相比于声明或者定义中一处有默认参数,没什么多余的意义。
2、容易犯错,就上例而言,假如在声明中设置默认参数值为183.5,在定义中设置默认参数值为167.5,将导致错误的产生,所以,只允许其中一处设置默认参数可以避免这种形式的错误。
 
    实验二:默认参数的所在的位置需要在调用者的前面
 
  1. #include <iostream>
  2. #include <tchar.h>
  3. using namespace std;
  4. void SetHeight(double dHeight = 183.5);
  5. int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
  6. {
  7. SetHeight();
  8. return 1;
  9. }
  10. void SetHeight(double dHeight)
  11. {
  12. cout << _T("身高为:") << dHeight << endl;
  13. }
上述代码编译通过。
 
  1. #include <iostream>
  2. #include <tchar.h>
  3. using namespace std;
  4. void SetHeight(double dHeight);
  5. void SetHeight(double dHeight = 183.5)
  6. {
  7. cout << _T("身高为:") << dHeight << endl;
  8. }
  9. int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
  10. {
  11. SetHeight();
  12. return 1;
  13. }
上述代码编译通过。
 
  1. #include <iostream>
  2. #include <tchar.h>
  3. using namespace std;
  4. void SetHeight(double dHeight = 183.5);
  5. void SetHeight(double dHeight)
  6. {
  7. cout << _T("身高为:") << dHeight << endl;
  8. }
  9. int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
  10. {
  11. SetHeight();
  12. return 1;
  13. }
上述代码编译通过。
 
  1. #include <iostream>
  2. #include <tchar.h>
  3. using namespace std;
  4. void SetHeight(double dHeight);
  5. int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
  6. {
  7. SetHeight();
  8. return 1;
  9. }
  10. void SetHeight(double dHeight = 183.5)
  11. {
  12. cout << _T("身高为:") << dHeight << endl;
  13. }
上述代码在编译的时候,编译器报告如下错误:
error C2660: 'SetHeight' : function does not take 0 parameters
 
实验二小结:编译通过的代码都有一个共同点,无论默认参数在函数声明语句中还是在函数定义语句中,默认参数的位置都在调用该函数的语句之前(代码的编写顺序),而编译失败的代码是因为调用函数的语句在默认参数所在的语句之后,由此得出一个结论:默认参数的语句所在的位置需要在主调函数的语句的前面。
 
    实验三:函数的声明和定义分别位于不同文件中的默认参数规则
 
  1. // Head.h
  2. #pragma once
  3. #include <tchar.h>
  4. #include <iostream>
  5. using namespace std;
  6. void SetHeight(double dHeight = 183.5);
 
  1. //Body.cpp
  2. #include "Head.h"
  1. void SetHeight(double dHeight)
  2. {
  3. cout << _T("身高为:") << dHeight << endl;
  4. }
 
  1. //Main.cpp
  2. #include "Head.h"
  3. int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
  4. {
  5. SetHeight();
  6. return 1;
  7. }
上述代码编译通过,因为Main.cpp中包含了Head.h,等价于将Head.h中的内容拷贝到#include"Head.h"的位置,所以在_main函数中的SetHeight()语句执行之前,就找到了带默认参数的函数声明。
 
  1. // Head.h
  2. #pragma once
  3. #include <tchar.h>
  4. #include <iostream>
  5. using namespace std;
  6. void SetHeight(double dHeight);
  1. //Body.cpp
  2. #include "Head.h"
  3. void SetHeight(double dHeight = 183.5)
  4. {
  5. cout << _T("身高为:") << dHeight << endl;
  6. }
  1. //Main.cpp
  2. #include "Head.h"
  3. int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
  4. {
  5. SetHeight();
  6. return 1;
  7. }
上述代码在编译的时候,编译器报告如下错误:
error C2660: 'SetHeight' : function does not take 0 parameters
由此,我猜测:编译器在编译到_tmain函数的SetHeight()语句的时候,只找到了SetHeight的声明,并以此判断出函数参数有错误。所以,SetHeight函数的定义部分并未出现在主调函数语句之前。
 
  1. // Head.h
  2. #pragma once
  3. #include <tchar.h>
  4. #include <iostream>
  5. using namespace std;
  6. void SetHeight(double dHeight);
  1. //Body.cpp
  2. #include "Head.h"
  3. void SetHeight(double dHeight = 183.5)
  4. {
  5. cout << _T("身高为:") << dHeight << endl;
  6. }
  7. int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
  8. {
  9. SetHeight();
  10. return 1;
  11. }
上述代码编译通过。
 
实验三小结:函数的声明和定义位于不同文件中的默认参数的规则同样要遵循实验二的结论。
 
上述的三个实验得出的两条结论:
1、编译器不允许默认参数同时存在于声明和定义中。
2、默认参数的语句所在的位置需要在主调函数的语句的前面。
同样适用于类的普通成员函数。

C++函数默认参数(转)的更多相关文章

  1. C++函数重载遇到了函数默认参数情况

    一.C++中的函数重载 什么是函数重载? 我的理解是: (1)用一个函数名定义不同的函数: (2)函数名和不同参数搭配时函数会有不同的含义: 举例说明: #include <stdio.h> ...

  2. 如何在ES5与ES6环境下处理函数默认参数

    函数默认值是一个很提高鲁棒性的东西(就是让程序更健壮)MDN关于函数默认参数的描述:函数默认参数允许在没有值或undefined被传入时使用默认形参. ES5 使用逻辑或||来实现 众所周知,在ES5 ...

  3. 【转】Python函数默认参数陷阱

    [转]Python函数默认参数陷阱 阅读目录 可变对象与不可变对象 函数默认参数陷阱 默认参数原理 避免 修饰器方法 扩展 参考 请看如下一段程序: def extend_list(v, li=[]) ...

  4. Python面试题目之Python函数默认参数陷阱

    请看如下一段程序: def extend_list(v, li=[]): li.append(v) return li list1 = extend_list(10) list2 = extend_l ...

  5. Python进阶-函数默认参数

    Python进阶-函数默认参数 写在前面 如非特别说明,下文均基于Python3 一.默认参数 python为了简化函数的调用,提供了默认参数机制: def pow(x, n = 2): r = 1 ...

  6. ES6函数默认参数(Default Parameters)

    语言更新时每一个新增的特性都是从千百万开发者需求里提取过来的,规范采用后能减少程序员的痛苦,带来便捷. 我们经常会这么写 function calc(x, y) { x = x || 0; y = y ...

  7. 【matlab】设定函数默认参数

    C++/java/python系列的语言,函数可以有默认值,通常类似如下的形式: funtion_name (param1, param2=default_value, ...) 到了matlab下发 ...

  8. ES6新特性(函数默认参数,箭头函数)

    ES6新特性之 函数参数的默认值写法 和 箭头函数. 1.函数参数的默认值 ES5中不能直接为函数的参数指定默认值,只能通过以下的变通方式:   从上面的代码可以看出存在一个问题,当传入的参数为0或者 ...

  9. C++函数默认参数

    C++中允许为函数提供默认参数,又名缺省参数. 使用默认参数时的注意事项: ① 有函数声明(原型)时,默认参数可以放在函数声明或者定义中,但只能放在二者之一 double sqrt(double f ...

  10. 3.C++内联函数,默认参数,占位参数

    本章主要内容: 1)内联函数(替代宏代码段) 2)默认参数 3)占位参数 1.C++的内联函数分析 1.1讲解内联函数之前,首先回忆下之前讲的define宏定义: 之前讲过宏定义会经过预处理器进行文本 ...

随机推荐

  1. Android程序调试

    1. 使用Log.d方法输出Debug日志信息. Log.d方法用来输出DEBUG故障日志信息,该方法有两种重载形式,其中开发人员经常用到的重载形式语法如下: public static int d( ...

  2. python2 python3编码问题记录

    最近在服务器上跑脚本,linux自带的是python 2.x,中文显示经常有问题,通过下面两篇终于弄懂了. https://www.cnblogs.com/575dsj/p/7112767.html ...

  3. android:Layout_weight的深刻理解

    最近写Demo,突然发现了Layout_weight这个属性,发现网上有很多关于这个属性的有意思的讨论,可是找了好多资料都没有找到一个能够说的清楚的,于是自己结合网上资料研究了一下,终于迎刃而解,写出 ...

  4. 【Python】Django filter 如何支持 or 条件过滤?

    from django.db.models import Q Item.objects.filter(Q(creator=owner) | Q(moderated=False)) 代码示例: if(r ...

  5. [CF 295A]Grag and Array[差分数列]

    题意: 有数列a[ ]; 操作op[ ] = { l, r, d }; 询问q[ ] = { x, y }; 操作表示对a的[ l, r ] 区间上每个数增加d; 询问表示执行[ x, y ]之间的o ...

  6. 机器学习学习笔记之一:K最近邻算法(KNN)

    算法 假定数据有M个特征,则这些数据相当于在M维空间内的点 \[X = \begin{pmatrix} x_{11} & x_{12} & ... & x_{1M} \\ x_ ...

  7. es6- ArrayBuffer

    ArrayBuffer对象.TypedArray视图和DataView视图是 JavaScript 操作二进制数据的一个接口. 简单说: ArrayBuffer对象代表原始的二进制数据, TypedA ...

  8. Php自动备份数据库实现方法

    然后再服务器开启 定时任务执行这个方法即可.

  9. 编程算法 - 从1到n整数中1出现的次数 代码(C)

    从1到n整数中1出现的次数 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 输入一个整数n, 求从1到n这n个整数的十进制表示中1出现的次数. ...

  10. 【微软100题】定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部。 如把字符串abcdef左旋转2位得到字符串cdefab。请实现字符串左旋转的函数。

    package test; /** * 定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部. 如把字符串abcdef左旋转2位得到字符串cdefab. 请实现字符串左旋转的函数. * ...