简介
在定义一个类时,如果类型名太长,可以用typedef 先在public里面定义类型名的别名,后面就一直用这个别名,如这里的index,后面几节都会用到。
所以看是不是重载,首先看形参表是否完全匹配,如果不匹配则是重载,不能看返回类型。
在类内定义的成员函数,自动会被定义为inline函数
指定为inline成员函数的三种方式
- 在类内定义的——自动指定为inline成员函数
- 在类内声明的函数,而且在声明时就指定为inline,那么类外按正常情况定义成员函数就行
- 在类内声明的函数,在声明时没有指定为inline,那么类外定义时在最前面加上inline。
========================================================================================================================
一、关于类定义的更多内容
1、同一类型的多个数据成员
- 类的数据成员的声明类似于普通变量的声明。如果一个类具有多个同一类型的数据成员,则这些成员可以在一个成员声明中指定,这种情况下,成员声明和普通变量声明是相同的。
//例如,可以定义一个名为Screen的类型来表示计算机上的窗口,每个Screen可以有一个保存窗口内容的string成员,以及三个string::size_type 成员:一个指定光标当前停留的字符,另外两个指定窗口的高度和宽度。
//如果使用命名空间 using namespace std 那么就不用有std::
class Screen{
public:
private:
std::string contents;//定义一个string对象,使用命名空间std,所以用std::string
std::string::size_type cursor;//string::size_type(string的下标类型)的数据成员,也有vector下标类型(vector<int>::size_type)
std::string::size_type height,width;
};
2、使用类型别名来简化类—- typedef
- 除了定义数据和函数成员外,类还可以定义自己的局部类型名字。如果为std::string::size_type 提供一个类型别名
class Screen{
public:
typedef std::string::size_type index;
private:
std::string contents;
index cursor;
index height,width;//用同义词替换
};
- 类所定义的类型名遵循任何其他成员的标准访问控制。将index的定义放在类的public部分,是因为希望用户使用这个名字。Screen类的使用者不必了解用string实现的底层细节。将这个类型设为public ,就允许用户使用这个名字
3、成员函数可被重载
像非成员函数一样,成员函数也可以被重载。
重载操作符(14.9.5)有特殊规则,是个例外,成员函数只能重载本类的其他成员函数。类的成员函数与普通的非成员函数以及在其他类中声明的函数不相关,也不能重载它们。重载的成员函数与普通的函数应用相同的规则:两个重载成员的形参数量和返回类型不能完全相同,调用非成员重载函数所用到的函数匹配(7.8.1)过程也应用于重载成员函数的调用。
7.8.1 重载函数
如果两个函数声明的返回类型和形参表(形参类型及个数)完全匹配,则将第二个函数声明视为第一个的重复声明。
如果两个函数的形参表完全相同,但返回类型不同,则第二个声明是错误的
函数不能仅仅基于不同的返回类型而实现重载(你还要看形参表),有些看起来不相同的形参表本质上是相同的。
所以看是不是重载,首先看形参表是否完全匹配,如果不匹配则是重载,不能看返回类型。
4、定义重载成员函数
//给出Screen类的两个重载成员,用于从窗口返回一个特点字符。两个重载成员中,一个版本返回当前光标指示的字符,另一个返回指定行列处的字符:
class Screen{
public:
typedef std::string::size_type index; //stirng类型的下标size_type类型的同义词index
char get() const{return contents[cursor];}//一个const类型的函数get,但是没有形参,返回的是一个char值。string1[size_type]。
char get(index ht,index wd) const; //声明一个const类型的函数get,返回char类型的值
private:
std::string contents;//string对象contents
index cursor;
index height,width;//stirng::size_type(下标)类型的数据成员.
};
//与任意的重载函数一样,给指定的函数调用提供适当数目和类型的实参来选择运行哪个版本:
Screen myscreen;
char ch = myscreen.get();//调用Screen::get();
ch = myscreen.get(0,0);//调用Screen::get(index , index)
5、显示指定inline成员函数
- 在类内定义的成员函数,自动会被定义为inline函数,如不接受实参的get 成员。也就是说,当他们被调用时,编译器将试图在同一行内扩展该函数(7.6)。也可以显示地将成员函数声明为inline:
-指定为inline成员函数的三种方式
- 在类内定义的——自动指定为inline成员函数
- 在类内声明的函数,而且在声明时就指定为inline,那么类外按正常情况定义成员函数就行
- 在类内声明的函数,在声明时没有指定为inline,那么类外定义时在最前面加上inline。
class Screen{
public:
typedef std::string::size_type index;
//第一种情况:类内定义的函数默认为inline函数,所以不需要显示说明
char get() const{return contents[cursor];}
//第二种情况:直接在声明的函数的最前面加上inline,显示指定为inline函数,然后再类外再定义一下就行。
inline char get(index ht,index wd) const;
//第三种情况:没有在类内定义,也没有指明为inline函数
index get_cursor() const;
};
//在类外定义的函数要指定作用域范围,函数在类内声明的时候已经指明是inline函数了
char Screen::get(index r,index c) const{
index row=r*width;
return contents[row+c];
}
//没有在类内定义的函数,也没有在类内指明为inline,所以类外定义时指明inline
//作用域不要忘记Screen::
//函数返回值类型是Screen::index
inline Screen::index Screen::get_cursor() const{
return cursor;
}