【1】函数定义体的花括号对后面是没有分号的,但是类定义体的花括号后面有分号;成员函数的定义如果放在了类定义中,那么函数名前就不需要冠以类名了;
只要是在类定义中包含的成员函数,就默认声明为内联的性质。另一方面,把成员函数写入类定义中,就使得类定义体的大小不可预见,同时编译是否真的将成员函数安排为内联,还要看函数是否足够简单,是否包含不适于内联运行的程序结构。所以,一般而言,短小的、不超过三行的成员函数定义放在类定义中是合适的。当然,在类外部实现的成员函数中也可以对编译提出内联要求。
【2】如果对象是以指针间接访问的形式操作的,则对象与成员函数之间就用双字符箭头“->”,即:
objectName->memberFunctionName(parameters);
或者将对象指针的间防形式用括号括起来,再加点操作符.加成员函数,即:
(*objectName). memberFunctionName(parameters);
【3】成员函数的操作,如果只是对对象进行读操作,则该成员函数可以设计为常成员函数。常成员函数的声明和定义在形式上必须一致,即在函数形参列表的右括号后面加上const,如:
类中声明:void print() const;
类外定义:inline void Date::print() const{
…
}
【4】重载+操作符:类中声明:friend Point operator+ ( const Point& a,const Point& b );
1. 不能创建新的操作符,例如@不是C++的操作符,不能定义其为C++的操作符;
2. :: . ? : 以及sizeof和typeof也不允许重载;
3. C++的操作符都是有优先级和结合性的,重载操作符后,其优先级和结合性是不会改变的。
4. 原先的操作符是单目的,重载也是单目形式;原先操作符是双目的,重载也是双目的,这是不能改变的;
5. 操作符的重载只能针对自定义类型,即在操作符定义的参数表中,至少有一个参数必须是自定义类型;因为任何内部数据类型的操作符默认定义,C++自认为已经完善,不允许编程者对C++内部系统重新定义;
6. 在设计函数时,参数若为类类型,则一般都用引用型;若为内部数据类型,则不用引用型,这是重要的经验之谈;
【5】“++”操作有前增量和后增量之差别,一个整数变量的前增量操作的结果与变量值是一致的,而且前增量操作的结果是左值,操作可以连贯。而后增量操作的结果是增量之前的变量值,它是临时变量,当表达式计算工作完成后,该临时变量随机消失,所以变量最终值与后增量结果是错位的,如:
int a=1,b=1,c=1,d=1;
(++a)++ //结果a=3
(b++)++;//结果b=2,(b++)的结果是临时变量,在其上加1随后又抛弃
++(++c);//结果c=3
++(d++);//结果d=2,与b相似
所以:
1. 前增量操作数与返回值是同一变量。在反映对象的前增量操作时,要求参数为对象的引用,返回的仍然是该对象参数的引用:
X& operator++(X& a); //前增量操作符
++a; //等价于operator++(a); 匹配上述操作符声明
2. 后增量操作符重载,同样要求参数为对象的引用,因为在调用的上下文中,实参将发生变化,而返回则为临时对象,所以为非引用的对象值。
虽然前后增量操作符为不同函数,但因为两个操作符声明的参数相同,所以在调用时无法区分,会引起编译报错,因此,在区别这两种操作符时,C++做了一个技术处理:
X& operator++(X& a,int b); //前增量操作符
a++; //等价于operator++(a,1); 匹配上述操作符声明
调用后增量操作符的参数匹配是违背函数参数匹配常规的,编译专门做了特殊处理;
【6】成员操作符和普通操作符不同的是,成员操作符定义中省略了第一个参数,因为成员函数总是与对象捆绑使用,被捆绑的对象就是被操作的第一个参数。因此,单目成员操作符没有参数,双目成员操作符只有一个参数。如,在类中定义+操作符就只用一个参数:
Point operator+(const Point& d){
Point s;
s.set(x+d.x,y+d.y);
return s;
}
【7】有类定义的地方,就可以使用类名和类中一切公有成员,这一范围称为类定义作用域。类定义作用域为包含类定义的花括号语句块,如果没有花括号语句块,则为从类定义开始的全部代码空间。
类作用域的范围则更为狭小,它仅包括类定义内部和所有其成员函数的定义体。在类作用域中,类的成员函数对数据成员和其他成员函数具有无限制的访问权;
【8】因为静态成员函数可以不以捆绑对象的形式调用,静态成员函数被调用时,没有当前对象的信息,所以静态成员函数不能访问数据成员。
【9】由于元素涉及私有成员,外部无法直接对其操作。对其频繁访问的要求造成频繁调用成员函数,于是导致调用开销明显增多,影响了性能。将一个普通函数声明为类的友元,就可以直接访问类的私有数据;
有远的声明方法为在有关的类定义中将函数声明为友元。
成员函数可以是另一个类的友元。例如,教师应该可以修改学生的成绩,可以访问学生类的私有数据,故将教师类中的批改成绩函数assignGrade成员函数声明为学生类的友元:
class Student; //前向声明 类型名使用之前必须先声明
class Teacher
{
Student* pList;
public:
//…
void assignGrade(Student& s);
};
class Student
{
Teacher* pT;
double grade;
public:
friend void Teacher::assignGrade(Student & s);
};
【10】整个类也可以是友元,此时,该类称为友元类。友类的每个成员函数都可以访问另一个类中的私有成员,如:
class Student{
Teacher* pT;
public:
friend class Teacher;
};