成员函数、非成员函数和友元函数
1.成员函数和非成员函数最大的区别在于成员函数可以是虚拟的而非成员函数不能,成员函数的优势是能够方便地进行动态绑定,实现多态。
说明一个函数为一个类的友元函数则该函数可以访问此类的私有数据和方法。
2.成员函数:
--->显式构造函数
C++中的explicit关键字用来修饰类的构造函数,表明该构造函数是显式的,隐式构造函数能够实现将该构造函数对应数据类型的数据转换为该类对象.
class MyClass
{
public:
MyClass(int num);
}
MyClass obj=10;//convert int to MyClass
如果在构造函数前加上关键字explicit,上述编译出错.
--->静态函数
类中,static型的成员函数,由于是类所拥有的,而不是具体对象所有的。
静态函数屏蔽了this指针,因此,如果成员函数作为回调函数,就应该用static去修饰它。
--->虚函数:
虚函数首先是一种成员函数,它可以在该类的派生类中被重新定义并被赋予另外一种处理功能。 注意多态不是函数重载。函数重载属于静态绑定,虚函数实现多态是动态绑定。
--->纯虚函数:
在抽象类中定义纯虚函数,必须在子类实现,不过子类也可以只是声明为纯虚函数,由 子类的子类实现。
--->协变返回类型:
一般来说,一个重写的函数与被它重写的函数必须具有相同的返回类型。 这个规则对于”协变返回类型(covariant return type)”的情形来说有所放松.
也就是说,若B是一个类类型,并且一个基类虚拟函数返回B *,那么一个重写的派生类函数可以返回D *, 其中的D公有派生于B(即D是一个(is-a)B).若基类虚函数返回B &,那么一个重写的派生类
函数可以返回一个D&.
考虑如下一个shape层次结构的clone操作: Class Shape {
Public:
//…
Virtual Shape *clone () const = 0; //prototype(原型)
//…
};
Class Circle : public Shape {
Public:
//…
Circle *clone () const ;
//…
};
3、友元函数
创建友元函数的步骤:
第一步:将原型放在类声明中,并在原型声明前加上关键字friend
第二步:编写函数定义。因为它不是成员函数,所以不要使用类的作用域。另外,不要在定义中使用关键字friend。
一个普通函数可以是多个类的友元函数。
一个类的成员函数也可以是另一个类的友元,从而可以使得一个类的成员函数可以操作另一个类的数据成员。
定义方法是在友元类中定义类的作用域如在类B中定义A的成员函数test为类B友元函数: friend void A::test(int &temp)
友元函数作为多个类的友元函数例:
class Country;
class Internet {
public:
Internet(char *name,char *address) // 改为:internet(const char *name , const char *address)
{
strcpy(Internet::name,name);
strcpy(Internet::address,address);
}
friend void ShowN(Internet &obj,Country &cn);//注意这里
public:
char name[20];
char address[20];
};
class Country {
public:
Country()
{
strcpy(cname,"中国");
}
friend void ShowN(Internet &obj,Country &cn);//注意这里
protected:
char cname[30];
};
void ShowN(Internet &obj,Country &cn) {
cout<<cn.cname<<"|"<<obj.name<<endl;
}
4、非成员函数
静态函数、内联函数和非静态函数。