一. 综述
在C++
中,我们使用“类”来描述“对象”,它是用户自己定义的数据类型,可以说“类”的实现是C++OOP
的核心。
那么设计类时要考虑哪些问题?
- 站在设计者和实现者的角度来考虑:考虑类中数据的存储和布局,有哪些必要的成员变量和成员函数等。
- 站在使用者的角度来考虑:哪些接口需要对使用者开放;哪些接口不对外分开放,只供自己内部使用。
- 含有继承关系的子类和父类应如何设计:比如设计一个车子父类,那么可能会有很多譬如卡车、轿车等子类,这时需要将这些车子的公共特性(比如都走机动车道、都是油驱等)抽取出来放到车子父类中,然后不同的车分别在子类中实现。子类可能不具有父类所有的属性和方法,也可能具有基类所没有的属性和方法。
二. 类基础
1、类的定义:C++
中使用关键字class
来定义类,如下:
class student { public: //公共的行为或属性:内部可以使用,外界也可以访问或者调用 string name; int num; void getStudentNum(); private: //私有的行为或属性:只能被本类内部成员函数访问,不能被外部所访问或调用 int age; void getStudentAge(); };
2、类的构成:
- 成员变量:
name
、num
(public
),age
(private
)。 - 成员函数:
getStudentNum()
(public
),getStudentAge()
(private
),此外,还有许多特殊成员函数,后面在慢慢讲解。
一般来说类的属性成员都应设置为private
,public
只留给那些被外界用来调用的函数接口, 但这并非是强制规定, 可以根据需要进行调整。
3、类成员的访问:
访问类成员时,如果是类的对象,使用对象名.成员名
来访问成员;如果是指向这个对象的指针,使用指针名->成员名
来访问成员。
student stu; stu.num = 100; //如果是类的对象,使用`对象名.成员名`来访问成员 student *pStu = &stu; pStu->num = 200; //如果是指向这个对象的指针,使用`指针名->成员名`来访问成员
4、类和结构的区别:
结构struct
是成员默认为public
的类class
,类class
成员默认是private
。为了便于记忆,可以理解struct
比较开放,class
比较保守。
struct A { int num; //未定义属性默认:public };
上面的结构定义等价于下面的类定义
class B { public: int num; //要定义public,否则默认是private }
虽然类和结构全部定义访问属性后等价,但是不建议类和结构混用。一般只有成员变量没有成员函数时可以用结构struct
定义,有成员函数可以定义成类class
,虽然这不是必须的,但是得有一个我们自己的标准来判断使用struct
定义还是class
,不要想用哪个用哪个。
三. 成员函数
C风格
初始化类成员变量:
class Time { public: int Hour; int Minute; int Second; }; void initTime(Time &stmptime, int tmphour, int tmpmin, int tmpsec) { stmptime.Hour = tmphour; stmptime.Minute = tmpmin; stmptime.Second = tmpsec; }
int main() { Time myTime; //类对象 initTime(myTime, 11, 14, 5); //初始化类对象 }
上面写法我们可以看到类Time
和函数initTime
并没有什么直接的联系,只是在主函数中调用了initTime
函数初始化了类Time
中的成员。因为是initTime
函数初始化了类Time
中的成员,理论上两者肯定是有关系的,只是我们的这种写法使得两者没有什么关系,那么如何使两者关联起来呢?
C++风格
初始化类成员变量(使用成员函数):
class Time { public: int Hour; int Minute; int Second; void initTime(int tmphour, int tmpmin, int tmpsec) //成员函数,实现也可以放在.cpp中 { Hour = tmphour; Minute = tmpmin; Second = tmpsec; } };
int main() { Time myTime; //类对象 myTime.initTime(11, 14, 5); //初始化类对象 }
四. 对象的拷贝
类对象本身是可以拷贝的,如:
Time myTime; //类对象 myTime.Hour = 12; myTime.Minute = 30; myTime.Second = 20; //对象拷贝(初始化另一对象) Time myTime2 = myTime; //方式一,值拷贝,内存不同 Time myTime3( myTime ); //方式二,值拷贝,内存不同 Time myTime4{ myTime }; //方式三,值拷贝,内存不同 Time myTime5 = { myTime }; //方式四,值拷贝,内存不同
默认情况下,这种类对象的拷贝,是每个成员变量逐个拷贝。如果我们在类Time
中定义适当的赋值运算符,是能够控制对象的拷贝行为的,就不会逐个拷贝了(后面讲)。
下雨天,最惬意的事莫过于躺在床上静静听雨,雨中入眠,连梦里也长出青苔。 |