經典C++筆試題解析8
--默認參數在哪指定?函數聲明還是定義?
Sailor_forever sailing_9806@163.com 轉載請注明
http://blog.csdn.net/sailor_8318/archive/2008/11/19/3337236.aspx
成員函數參數的默認值是在聲明里賦,還是在定義里?
class CAbc
{
public:
static int m_abc;
CAbc(){}
static void set(int abc);
int fn(int a,int b=0,int c=5);
//int fn(int a,int b,int c);
};
void CAbc::set(int abc)
{
m_abc=abc;
}
//int CAbc::fn(int a,int b=0,int c=5)
//redefinition of default parameter : parameter 3
int CAbc::fn(int a,int b,int c)
{
cout<<a << b << c << endl;
return a;
}
int CAbc::m_abc=1000;
int main(int argc, char* argv[])
{
CAbc a;
a.fn(6);
a.set(10);
return 0;
}
聲明是用戶可以看到的部分,客戶非常信任地使用這個特性,希望得到一定的結果,但是你在實現里使用了不同的缺省值,那么將是災難性的。因此編譯器禁止聲明和定義時同時定義缺省參數值。
類的成員函數的參數表在聲明時默認參數位於參數表右部,如int fn(int a,int b=0,int c=5)之類的,但在它定義的時候則不能加默認參數,只能寫int fn(int a,int b,int c);
若聲明時沒有定義缺省參數值,那么在定義成員函數時可以定義缺省參數值。但這種情況通常用戶是看不見的,因此應避免。
對於非類中的函數,在函數聲明中定義默認參數的另外一個好處時,可以利用聲明來隨意更改默認參數的值。
//int fglobal(int a,int b=2,int c=5)
//redefinition of default parameter : parameter 3
int fglobal(int a,int b,int c)
{
cout<<a << b <<c<< endl;
return a;
}
int fglobal(int a,int b=2,int c=5); // 全局的申明
int CAbc::m_abc=1000;
int main(int argc, char* argv[])
{
CAbc a;
a.fn();
//fglobal(); //此時用的全局申明,無第一個參數不行
fglobal(1);
int fglobal(int a=2,int b=3,int c=5); // 局部的申明,不管上述默認參數是在定義還是申明中
fglobal();
::fglobal(3); // 此時將采用全局申明
return 0;
}
//205
//125
//235
//325
}
實踐證明,缺省參數可以在定義中,也可以在聲明中,只要全局的聲明和定義中只有一個帶參數即可
局部的聲明中可以隨便改變默認參數(不管上述默認參數是在定義中還是在聲明中)。在下一次改變之前,此參數將一直生效,並將覆蓋全局的申明。若要使用全局的聲明默認參數,可以加“::”
經典C++筆試題解析7
--如何利用成員變量作為成員函數的默認參數
Sailor_forever sailing_9806@163.com 轉載請注明
http://blog.csdn.net/sailor_8318/archive/2008/11/19/3337236.aspx
如何在類成員函數中默認引用類成員?
class CAbc;
class CAbc
{
private:
int m_abc;
public:
void fun0(int &p=NULL)//編譯錯誤
{
printf("%d",p);
}
void fun1(const int &p=NULL)//編譯通過
{
printf("%d",p);
}
void fun2(int &p=this->m_abc)//編譯錯誤
{
printf("%d",p);
}
void fun3(const int &p=m_abc)//編譯錯誤
{
printf("%d",p);
}
};
引用必有初始值,且不能為Null
class CAbc;
class CAbc
{
public:
int m_abc;
CAbc(){}
void set(int abc);
void fun( const int &p=m_abc) // const只是表示其為輸入參數而已,可以去掉
{
printf("%d/n",p);
}
};
//提示: error C2648 將成員作為默認參數使用要求靜態成員。
一個類中,為什么不能將數據成員做為成員函數的默認參數?
標准規定這么一個限制條件是有其理由的,非靜態成員如果在成員函數被調用前沒有被初始化,此時編譯器無法確認函數參數的默認值是多少。而標准這樣做就把錯誤的發現提前到編譯期。
解決辦法是將缺省參數值是靜態綁定在靜態類型成員上面。
以下代碼通過了
class CAbc;
class CAbc
{
public:
static int m_abc;
CAbc(){}
void set(int abc);
void fun( const int &p=m_abc) // const只是表示其為輸入參數而已,可以去掉
{
printf("%d/n",p);
}
};
void CAbc::set(int abc)
{
m_abc=abc;
}
int CAbc::m_abc=1000;
int main(int argc, char* argv[])
{
CAbc a;
a.fun();
a.set(10);
a.fun();
return 0;
}
