1.为什么C语言不支持函数重载而C++支持?
(什么是函数重载?为什么C语言不支持函数重载?而C++能支持函数重载?)
函数重载是用来描述同名函数具有相同或者相似的功能,但数据类型或者是参数不同的函数管理操作。
函数名经过C++编译器处理过后包含了原函数名,函数参数数量及返回类型信息,而C语言不会对函数名进行处理。
2.重载和覆写有什么区别
重载是编写一个与已有函数同名但是参数表不同(参数数量或参数类型不同)的方法,它具有如下所示的特征。
1)方法名必须相同;
2)参数列表必须不相同,与参数列表的顺序无关;
3)返回值类型可以不相同;
覆写诗派生类重写基类的虚函数,它具有如下特征。
1)只有虚方法和抽象方法才能够被覆写;
2)相同的函数名;
3)相同的参数列表;
4)相同的返回值。
重载是一种语法规则,有编译器在编译阶段完成,不属于面向对象编程;而覆写是由运行阶段决定的,是面向对象编程的重要特征。
3.编程题——MyString类的编写
(重载=和+运算符)
对于下面的类MyString,要求重载一些运算符可以计算表达式a+b+c.
其中,a,b,c都是类MyString的对象。请重载相应的运算符并编写程序测试。
class MyString
{
public:
MyString(char *s)
{
str=new char[strlen(s)+1];
strcpy(str,s);
}
~MyString()
{
delete []str;
}
private:
char *str;
}
为了实现a=b+c;这个表达式,需要重载两个运算符,一个是”+”运算符,用于b+c,另一个是”=”运算符,用于对象a的覆值。代码如下:
#include<iostream>
using namespace std;
class MyString
{
public:
MyString(char *s)//参数为字符指针的构造函数
{
str=new char[strlen(s)+1];
strcpy(str,s);
}
~MyString()//析构函数释放str堆内存
{
delete []str;
}
MyString & operator=(MyString &string)//覆值函数。重载=
{
if(this==&string)
{
return *this;
}
if(str!=NULL)//释放内存
{
delete []str;
}
str=new char[strlen(string.str)+1];//申请内存
strcpy(str,string.str);//复制字符串内容
return *this;
}
MyString & operator+(MyString &string)//重载+(改变被加对象)
{
char *temp=str;
str=new char[strlen(temp)+strlen(string.str)+1];
strcpy(str,temp);//复制第一个字符串
delete []temp;
strcat(str,string.str);//连接第二个字符串
return *this;
}
/*MyString & operator + (MyString &string)//重载+(不改变被加对象)
{
MyString *pString=new MyString("");//堆内存中构造对象
pString->str=new char[strlen(str)+strlen(string.str)+1];
strcpy(pString->str,str);//复制第一个字符串
strcat(pString->str,string.str);//连接第二个字符串
return *pString;//返回堆中的对象
}*/
void print()//测试打印str成员
{
cout<<str<<endl;
}
private:
char *str;
}
/* //MyString类的友员,要求str成员是public访问权限
MyString & operator+(MyString &left,MyString &right)//重载+(不改变被加对象)
{
MyString *pString=new MyString("");
pString->str=new char[strlen(left.str)+strlen(right.str)+1];
strcpy(pString->str,left.str);//复制第一个字符串
strcat(pString->str,string.str);//连接第二个字符串
return *pString;
}*/
int main(int argc,char* argv[])
{
MyString a("hello");
MyString b("world");
MyString c("");
c=c+a;
c.print();
c=c+b;
c.print();
c=a+b;
a.print();
c.print();
return 0;
}
这里有3个版本的‘+’操作符重载函数,它们都是调用strcpy复制第一个字符串,然后调用strcat连接第二个字符串。
第一个版本返回*this对象,它改变了被加对象的内容。使用第一个‘+’操作符重载函数的版本内容如下:
1.hello
2.hello world
3.hello world
4.hello world
第2个版本和第3个版本都是返回堆中构造的对象,它们没有改变被加对象内容。区别如下:
1)第2个版本属于类的成员函数,而第3个版本是类的友员函数。
2)第2个版本的参数为1个,而第3个版本的参数为2个,因为友员函数不含有this指针。
3)由于类的友员函数不能使用私有成员,因此在这里使用第3个版本时需要把str成员的访问权限改为public。
使用这两个’+’操作符重载函数版本的执行结果:
1.hello
2.hello world
3.hello(对象a的str成员没有被改变)
4.hello world
选择何种版本的’+’操作符重载函数要取决于实际情况。
4.看代码写输出——new操作符重载的使用
下列程序中主函数的new是类中new操作符重载。但是new后面只有一个参数0xa5,而类中函数的声明有两个参数。怎么会调用这个类的呢?
#include<malloc.h>
#include<memory.h>
class Blanks
{
public:
void *operator new(size_t stAllocateBlock,char chInit);
};
void *Blanks::operator new(size_t stAllocateBlock,char chInit)
{
void *pvTemp=malloc(stAllocateBlock);
if(pvTemp!=0)
memset(pvTemp,chInit,stAllocateBlock);
return pvTemp;
}
int main()
{
Blanks *a5=new(0xa5) Blanks;
return a5!=0;
}
这里有以下几点需要说明。
1)重载new操作符第一个参数必须是size_t类型的,并且传入的值就是类的大小。本题中类的大小是1。如果类中含有一个int类型成员(int占4个字节),那么参数stAllocateBlock的值为4。
2)代码第20行中的0xa5表示第二个参数的大小,也就是chInit为0xa5。
3)代码第14行,用chInit初始化分配的那块内存。
4)当执行代码第20行时,首先调用Blanks重载的new操作符函数,然后使用默认的构造函数初始化对象,最后用这个Blanks对象地址初始化a5。