关于C++函数主题

来源:互联网 发布:python应用范围 编辑:程序博客网 时间:2024/06/04 18:20

参数类型检查

C++是一种静态强类型的语言,对于每一次的调用,编译时都会检查其实参,调用函数时,对于每一个实参,其类型都必须与对应的形参类型相同,或具有可被转化为该形参类型的类型。

参数传递

利用const 引用来避免复制,如果使用引用形参的唯一目的是避免复制实参,则应将形参定义为const引用。

const引用形参只能与完全同类型的非const对象关联

应该将不需要修改的引用形参定义为const引用,普通的非const引用形参在使用时不太灵活,这样的形参既不能用非const对象初始化,也不能用字面值或产生右值的表达式初始化。

string::size_type find_char(string &s, char c)

{

       string::size_type i=0;

       while(i!=s.size() && s[i]!=c)

       {

              i++;

       }

       return i;

};

int main()

{

       cout<<find_char("hello",'o')<<endl; //用字符串hello当做实参,传递给非const引用,调用失败,如果将形参改为const 引用,调用成功

       getchar();

       return 0;

}

合成的默认构造函数

合成的默认构造函数一般适用于仅包含类类型成员的类,而对于内置类型和复合类型成员的类,则通常应该定义他们自己的默认构造函数初始化这些成员。

内置类型成员的初值依赖于对象如何定义,如果对象在全局作用域中定义(不在任何函数内)或定义为静态局部对象,则这些成员应该初始化为0,如果对象在局部作用域中定义,则这些成员没有初始化。

数组形参

通常将数组形参直接定义为指针要比使用数组语法好,这样明确函数要操纵的是指向数组元素的指针,而不是数组本身,当编译器检查数组形参关联的实参时,只会检查实参是不是指针,指针的类型是否匹配,而不会检查长度。

通常情况下,数组形参以普通的非引用类型传递,此时数组会转换为指针,一般来说非引用类型的形参会初始化为其相应类型的实参副本,形参复制的是数组元素指针的值而不是数组本身。

通过引用来传递数组

如果形参是数组的引用,编译器不会讲数组实参转换为指针,而是传递数组的引用本身,此时,编译器会检查数组实参的大小和形参的大小是否匹配。

此外,引用数组的定义是int (&arr)[10] ,其中的括号不能省

 

void printValues1(int (&arr)[10])

{

       for(int i=0;i<10;i++)

       {

              cout<<arr[i]<<endl;

       }

}

void printvalues2(int *p,int len)

{

       while(len--)

       {

              cout<<*p<<endl;

              p++;

       }

}

int main()

{

       int k[10]={1,2,3,4,5,6,7,8,9,10};

       int a[5]={1,2,3,4,5};

printValues1(k);

       printvalues2(a,5);

       getchar();

       return 0;

}

返回非引用类型

函数的返回值用于初始化在调用函数处创建的临时对象,在求解表达式时,如果需要一个地方存储其运算结果,编译器会创建这个临时对象,如果返回类型不是引用,在调用函数的地方会将函数的返回值复制给临时对象,返回值可以使函数的局部对象,也可以是求解表达式的结果。

int func(const int a)

{

       int b=a;

       return b;

}

int main()

{

       int t=func(10);

       cout<<t<<endl;

       getchar();

       return 0;

}

返回引用

当函数返回引用类型时,没有复制返回值,相反返回的是对象本身。

const string &shortestString(const string &s1,const string & s2)

{

       return s1.size()<s2.size()?s1:s2;

}

int main()

{

       string s1("hello"),s2("what");

       shortestString(s1,s2);

       getchar();

       return 0;

}

千万不要返回局部对象的引用和局部对象指针

当函数执行完毕时,将释放分配给局部对象的存储空间,任何对局部对象的引用都会指向不确定的内存。

const string &shortestString(const string & s1)

{

string temp=s1;

return temp;

}

int main()

{

       string s1("hello"),s2("what");

       s2=shortestString(s1);

       getchar();

       return 0;

}

运行报错

重载函数

void print(int i)

{

       cout<<"int_i"<<endl;

       cout<<i<<endl;

}

void print()

{

cout<<"hello"<<endl;

}

int main()

{

       print(5);

       print();

       getchar();

       return 0;

}

两个重载函数print(int i) print

在任何程序中仅有一个main示例,main函数不能重载

如果局部地声明一个函数,则该函数将屏蔽而不是重载在外层作用域声明的同名函数,重载函数应该在同一个作用域中声明。

void print(int i)

{

cout<<"int_i"<<endl;

cout<<i<<endl;

}

void print()

{

cout<<"hello"<<endl;

}

int main()

{

void print(string str);

print(5);

getchar();

return 0;

}

重载和const形参

仅当形参是引用或指针时,形参是否为const才有影响

可基于函数的引用形参是指向const对象还是指向非const对象,实现函数的重载,将引用形参定义为const来重载函数,如果形参不是引用,那么不能利用是否为const来实现重载。

Record lookupAccount &);

Record lookupconst Account &);

const Account a(0);

Account b;

Lookup(a); //调用 Record lookupconst Account &);

Lookup(b); //调用 Record lookupAccount &);

指向函数的指针

函数指针是指指向函数而非指向对象的指针。

bool (*cmpFcn)(const string &,const string&);cmpFcn声明为指向函数的指针,用typedef简化函数指针的定义

typedef bool (*cmpFcn)(const string &,const string&) cmpFcn定义为指向返回bool类型并带有两个const string 引用形参的函数的指针,

指向函数的指针的初始化和赋值

在引用函数名但有没有调用该函数时,函数名将自动解释为指向函数的指针,如下所示:

bool lengthCompare(const string &,const string&); lengthCompare被解析为该类型的函数指针。

返回指向函数的指针

函数可以返回指向函数的指针,如下所示:

Int *ffint))(int*int);

ff是函数,带有形参为int型,该函数的返回类型是函数指针,指向int型,参数是(int *int)。