函数声明和函数定义中的默认参数浅析
2015-04-10 14:01
369 查看
默认参数是存在于函数的声明中,还是函数的定义中呢?
我在VS6.0和VS2008下做了如下实验,并做出了简单的总结,有不足或者不准确的地方,欢迎大家拍砖,我会及时修正相关内容。
实验一:默认参数不能同时存在于函数声明和函数定义中。
#include <iostream>
#include <tchar.h>
using namespace std;
void SetHeight(double dHeight = 183.5);
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
SetHeight(181.5);
return 1;
}
void SetHeight(double dHeight = 183.5)
{
cout << _T("身高为:") << dHeight << endl;
}
然后调整一下顺序(本文的例子只用于实验,并不侧重于代码本身是否有意义):
#include <iostream>
#include <tchar.h>
using namespace std;
void SetHeight(double dHeight = 183.5);
void SetHeight(double dHeight = 183.5)
{
cout << _T("身高为:") << dHeight << endl;
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
SetHeight(181.5);
return 1;
}
两处代码编译的时候,编译器都会报告如下错误:
error C2572: 'SetHeight' : redefinition of default parameter : parameter 1,see declaration of 'SetHeight'
实验一小结:编译器不允许默认参数同时存在于声明和定义中,之所以这个做,个人猜测:
1、没必要,声明和定义都有默认参数相比于声明或者定义中一处有默认参数,没什么多余的意义。
2、容易犯错,就上例而言,假如在声明中设置默认参数值为183.5,在定义中设置默认参数值为167.5,将导致错误的产生,所以,只允许其中一处设置默认参数可以避免这种形式的错误。
实验二:默认参数的所在的位置需要在调用者的前面
#include <iostream>
#include <tchar.h>
using namespace std;
void SetHeight(double dHeight = 183.5);
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
SetHeight();
return 1;
}
void SetHeight(double dHeight)
{
cout << _T("身高为:") << dHeight << endl;
}
上述代码编译通过。
#include <iostream>
#include <tchar.h>
using namespace std;
void SetHeight(double dHeight);
void SetHeight(double dHeight = 183.5)
{
cout << _T("身高为:") << dHeight << endl;
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
SetHeight();
return 1;
}
上述代码编译通过。
#include <iostream>
#include <tchar.h>
using namespace std;
void SetHeight(double dHeight = 183.5);
void SetHeight(double dHeight)
{
cout << _T("身高为:") << dHeight << endl;
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
SetHeight();
return 1;
}
上述代码编译通过。
#include <iostream>
#include <tchar.h>
using namespace std;
void SetHeight(double dHeight);
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
SetHeight();
return 1;
}
void SetHeight(double dHeight = 183.5)
{
cout << _T("身高为:") << dHeight << endl;
}
上述代码在编译的时候,编译器报告如下错误:
error C2660: 'SetHeight' : function does not take 0 parameters
实验二小结:编译通过的代码都有一个共同点,无论默认参数在函数声明语句中还是在函数定义语句中,默认参数的位置都在调用该函数的语句之前(代码的编写顺序),而编译失败的代码是因为调用函数的语句在默认参数所在的语句之后,由此得出一个结论:默认参数的语句所在的位置需要在主调函数的语句的前面。
实验三:函数的声明和定义分别位于不同文件中的默认参数规则
// Head.h
#pragma once
#include <tchar.h>
#include <iostream>
using namespace std;
void SetHeight(double dHeight = 183.5);
//Body.cpp
#include "Head.h"
void SetHeight(double dHeight)
{
cout << _T("身高为:") << dHeight << endl;
}
//Main.cpp
#include "Head.h"
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
SetHeight();
return 1;
}
上述代码编译通过,因为Main.cpp中包含了Head.h,等价于将Head.h中的内容拷贝到#include"Head.h"的位置,所以在_main函数中的SetHeight()语句执行之前,就找到了带默认参数的函数声明。
// Head.h
#pragma once
#include <tchar.h>
#include <iostream>
using namespace std;
void SetHeight(double dHeight);
//Body.cpp
#include "Head.h"
void SetHeight(double dHeight = 183.5)
{
cout << _T("身高为:") << dHeight << endl;
}
//Main.cpp
#include "Head.h"
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
SetHeight();
return 1;
}
上述代码在编译的时候,编译器报告如下错误:
error C2660: 'SetHeight' : function does not take 0 parameters
由此,我猜测:编译器在编译到_tmain函数的SetHeight()语句的时候,只找到了SetHeight的声明,并以此判断出函数参数有错误。所以,SetHeight函数的定义部分并未出现在主调函数语句之前。
// Head.h
#pragma once
#include <tchar.h>
#include <iostream>
using namespace std;
void SetHeight(double dHeight);
//Body.cpp
#include "Head.h"
void SetHeight(double dHeight = 183.5)
{
cout << _T("身高为:") << dHeight << endl;
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
SetHeight();
return 1;
}
上述代码编译通过。
实验三小结:函数的声明和定义位于不同文件中的默认参数的规则同样要遵循实验二的结论。
上述的三个实验得出的两条结论:
1、编译器不允许默认参数同时存在于声明和定义中。
2、默认参数的语句所在的位置需要在主调函数的语句的前面。
同样适用于类的普通成员函数。
我在VS6.0和VS2008下做了如下实验,并做出了简单的总结,有不足或者不准确的地方,欢迎大家拍砖,我会及时修正相关内容。
实验一:默认参数不能同时存在于函数声明和函数定义中。
#include <iostream>
#include <tchar.h>
using namespace std;
void SetHeight(double dHeight = 183.5);
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
SetHeight(181.5);
return 1;
}
void SetHeight(double dHeight = 183.5)
{
cout << _T("身高为:") << dHeight << endl;
}
然后调整一下顺序(本文的例子只用于实验,并不侧重于代码本身是否有意义):
#include <iostream>
#include <tchar.h>
using namespace std;
void SetHeight(double dHeight = 183.5);
void SetHeight(double dHeight = 183.5)
{
cout << _T("身高为:") << dHeight << endl;
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
SetHeight(181.5);
return 1;
}
两处代码编译的时候,编译器都会报告如下错误:
error C2572: 'SetHeight' : redefinition of default parameter : parameter 1,see declaration of 'SetHeight'
实验一小结:编译器不允许默认参数同时存在于声明和定义中,之所以这个做,个人猜测:
1、没必要,声明和定义都有默认参数相比于声明或者定义中一处有默认参数,没什么多余的意义。
2、容易犯错,就上例而言,假如在声明中设置默认参数值为183.5,在定义中设置默认参数值为167.5,将导致错误的产生,所以,只允许其中一处设置默认参数可以避免这种形式的错误。
实验二:默认参数的所在的位置需要在调用者的前面
#include <iostream>
#include <tchar.h>
using namespace std;
void SetHeight(double dHeight = 183.5);
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
SetHeight();
return 1;
}
void SetHeight(double dHeight)
{
cout << _T("身高为:") << dHeight << endl;
}
上述代码编译通过。
#include <iostream>
#include <tchar.h>
using namespace std;
void SetHeight(double dHeight);
void SetHeight(double dHeight = 183.5)
{
cout << _T("身高为:") << dHeight << endl;
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
SetHeight();
return 1;
}
上述代码编译通过。
#include <iostream>
#include <tchar.h>
using namespace std;
void SetHeight(double dHeight = 183.5);
void SetHeight(double dHeight)
{
cout << _T("身高为:") << dHeight << endl;
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
SetHeight();
return 1;
}
上述代码编译通过。
#include <iostream>
#include <tchar.h>
using namespace std;
void SetHeight(double dHeight);
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
SetHeight();
return 1;
}
void SetHeight(double dHeight = 183.5)
{
cout << _T("身高为:") << dHeight << endl;
}
上述代码在编译的时候,编译器报告如下错误:
error C2660: 'SetHeight' : function does not take 0 parameters
实验二小结:编译通过的代码都有一个共同点,无论默认参数在函数声明语句中还是在函数定义语句中,默认参数的位置都在调用该函数的语句之前(代码的编写顺序),而编译失败的代码是因为调用函数的语句在默认参数所在的语句之后,由此得出一个结论:默认参数的语句所在的位置需要在主调函数的语句的前面。
实验三:函数的声明和定义分别位于不同文件中的默认参数规则
// Head.h
#pragma once
#include <tchar.h>
#include <iostream>
using namespace std;
void SetHeight(double dHeight = 183.5);
//Body.cpp
#include "Head.h"
void SetHeight(double dHeight)
{
cout << _T("身高为:") << dHeight << endl;
}
//Main.cpp
#include "Head.h"
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
SetHeight();
return 1;
}
上述代码编译通过,因为Main.cpp中包含了Head.h,等价于将Head.h中的内容拷贝到#include"Head.h"的位置,所以在_main函数中的SetHeight()语句执行之前,就找到了带默认参数的函数声明。
// Head.h
#pragma once
#include <tchar.h>
#include <iostream>
using namespace std;
void SetHeight(double dHeight);
//Body.cpp
#include "Head.h"
void SetHeight(double dHeight = 183.5)
{
cout << _T("身高为:") << dHeight << endl;
}
//Main.cpp
#include "Head.h"
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
SetHeight();
return 1;
}
上述代码在编译的时候,编译器报告如下错误:
error C2660: 'SetHeight' : function does not take 0 parameters
由此,我猜测:编译器在编译到_tmain函数的SetHeight()语句的时候,只找到了SetHeight的声明,并以此判断出函数参数有错误。所以,SetHeight函数的定义部分并未出现在主调函数语句之前。
// Head.h
#pragma once
#include <tchar.h>
#include <iostream>
using namespace std;
void SetHeight(double dHeight);
//Body.cpp
#include "Head.h"
void SetHeight(double dHeight = 183.5)
{
cout << _T("身高为:") << dHeight << endl;
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
SetHeight();
return 1;
}
上述代码编译通过。
实验三小结:函数的声明和定义位于不同文件中的默认参数的规则同样要遵循实验二的结论。
上述的三个实验得出的两条结论:
1、编译器不允许默认参数同时存在于声明和定义中。
2、默认参数的语句所在的位置需要在主调函数的语句的前面。
同样适用于类的普通成员函数。
相关文章推荐
- 函数声明和函数定义中的默认参数浅析
- 避免对函数中继承得来的默认参数值进行重定义
- A Byte of Python 笔记(5)函数:定义、形参、局部变量、默认参数、关键参数
- Python定义函数默认参数
- 【转】深入理解C++的动态绑定和静态绑定 & 不要重定义虚函数中的默认参数
- python-在定义函数时,不定长参数中,默认值参数不能放在必选参数前面
- C/C++中默认参数在哪指定?函数声明还是定义?默认参数需放在右边
- 绝不重定义继承的函数默认参数
- 零基础学python-2.19 定义函数、调用函数与默认参数
- Python中函数及默认参数的定义与调用操作实例分析
- COM接口函数参数定义如果缺省[in][out]则默认为[in]
- js定义函数和默认参数
- 复习4次课(12月1日) 1.1 函数定义 1.2 函数的参数 1.3 函数的默认参数 1.4 函数的变量 1.5 函数的返回值 1.6 多类型传值和冗余参数 1.7 函数的递归调用
- 函数定义、函数的参数、函数的默认参数
- Scala 学习笔记(五)------定义函数指定默认参数
- 读书笔记 effective c++ Item 37 永远不要重新定义继承而来的函数默认参数值
- 函数的默认参数重复定义问题
- 第37条:避免对函数中继承得来的默认参数值进行重定义
- 函数声明与函数定义的参数
- 函数参数默认值定义