32.c/c++程序员面试宝典-类成员函数
在类内部,声明成员函数是必须的,而定义成员函数则是可选的。在类外部定义的成员函数必须指明他们是在类的作用域中。
面试题123 什么是类成员函数?有哪些特别的类成员函数***
分析:类的成员可以是数据,函数或者类型别名。类的成员中的函数就是类的成员函数。类的成员函数声明类所具有的方法。
类的成员函数可以分为内联函数和外联函数两种。内联函数是指那些定义在类体内的成员函数,即该函数的函数体放在类体内。而申明在类体内,定义在类体外的成员函数叫外联函数。外联函数的函数体在类的实现部分。
内联函数在调用时不是像一般函数那样要转去执行被调用函数的函数体,执行完成后再转回调用函数中,执行其后语句,而是在调用函数处用内联函数体的代码来替换,这样将会节省调用开销,提高运行速度。
内联函数与带参数的宏定义进行作比较,它们的代码效率是相同的。但是内联函数要优于宏定义,因为内联函数遵循类型和作用域规则,它与一般函数更相近。在一些编译器中,一旦关上内联扩展,将与一般函数一样进行调用,高度比较方便。
内联函数也有一定的局限性。就是函数中的执行代码不能过多。如果内联函数的函数体过大,一般编译器会放弃内联方式,而采用普通的方式调用函数。这样,内联函数就和普通函数执行效率一样了。可以使用inline关键字,将定义在类外部的函数定义为内联函数,一个示例代码如下:
class TableClass
{
private:
int a, b;
public:
int add() //定义内联函数,不使用关键字inline
{
return a+b;
}
inline int dec() //定义内联函数,使用关键字inline
{
return a-b;
}
int GetNum();
};
inline int TableClass::GetNum() //使用关键字inline
{
return a;
}
上面代码中,类内部的函数不论有没有使用关键字inline,都被默认为使内联函数,而外部的函数使用了inline关键字定义的为类的内联函数。
由于可以使用构造函数隐式的初始化类对象,所以构造函数也是类的成员函数,它在语法上比其他成员函数要求更加严格。因此,默认构造函数也是类的成员函数。
析构函数和构造函数类似,也是类的成员函数。在语法要求上,析构函数比构造函数要求更加严格,在函数接口不允许有返回值,在函数体内也不允许使用return,析构函数也不允许带有参数。
【答案】类成员中的函数就是类的成员函数,特别的类成员函数有构造函数和析构函数。
面试题124 什么是静态函数?如何使用静态函数***
分析:静态函数就是使用static关键字修饰的函数,静态成员函数的声明除了在类体的函数声明前加上关键字static,以及不能声明为const或者volatile之外,与非静态成员函数相同。出现在类体之外的函数定义不能制定关键字static。如果static intfunc()不是出现在类中,它就不是一个静态成员函数,而只是一个普通的全局函数,但是由于static的限制,它只能在文件所在的编译单位内使用,不能在其他编译单位内使用。
说明:静态函数没有this指针
静态函数不能被其他文件所用,其他文件中可以定义相同名字的函数,在类中如果函数调用的结果不会访问或者修改任何对象数据成员,这样的成员声明为静态成员函数比较好。一个静态函数的示例代码如下:
#include<iostream.h>
static void fn(); //声明为静态函数
void main()
{
fn();
}
void fn() //定义静态函数
{
int n=10;
cout<<n<<endl;
}
【答案】静态函数是使用static修饰符修饰的函数,静态函数没有this指针,只能访问静态变量。在类中如果函数调用的结果不会访问或者修改任何对象数据成员,这样的成员声明为静态成员函数比较好。
面试题125 静态函数能访问类的私有成员***
分析:类的静态成员函数可以访问类的私有成员,但是静态成员函数只能直接访问类的静态私有成员,因为静态成员函数是不可以直接访问非静态成员的。但是静态成员函数可以借助对象名和指针来访问类的非静态私有成员。
静态函数是不可以直接访问类的私有变量的。但是可以通过宏定义替换Private为public等方法来实现对类的私有成员的访问。
【答案】静态函数只能直接访问类的静态私有成员,静态函数不可以直接访问类的非静态私有成员,但是可以通过自定义的一些特殊方法比如宏替换访问类的非静态私有成员。
面试题126 一个类可以访问另一个类的私有成员吗***
分析:类的私有成员是不可以被外部类访问的,但是可以用宏定义的特殊方法来访问类的私有成员。示例代码如下:
class ClxECS //定义一个类
{
private:
int iPrivate;
}
在这种情况下定义如下函数:
void ECS_test() //不可以通过编译
{
ClxECS lx;
lx.iPrivate=13;
cout<<lx.iPrivate<<endl;
}
void main()
{
ECS_test();
}
但是如果在类的定义前加上一行代码如下:
#define private public
这样就可以访问了,同样这种方法对于保护成员也是适用的。
#define protected public
注意:这是一个非正规的手段,它将破坏类的所有封装性。而c++中的#define的存在也是为了跟c兼容。所以只有在非常特殊的情况下,才会用这种非正规方法访问类的私有或保护成员。
【答案】外部类可以使用宏定义等特殊方法来实现访问类的私有成员。