CPP学习备忘[6] 类

 

【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;

};

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值