第7章 类
摘要:在看Qt时,其中:在.cpp的文件(是类的源文件)---实现槽,在.h的文件中声明槽。 于是打算在这篇随笔中尽可能多的通学C++语言中的类。
--------------------------------------------------------------------------------------------------
一. 在《C/C++程序设计》 吴国凤、吴善立主编中10.3节的---类与对象
1.类和对象的定义
1) 类的声明
实际上类是一种新的数据类型。 它是把数据和作用在这些数据上的操作组合在一起(是进行封装和数据隐藏的基本工具)。
1 //一个日期类的说明
2
3 class Cdata{
4 public:
5 void SetDate(inty ,intm, int d)
6 int IsLeap Year();
7 void print ();
8 private:
9 int year,month,day;
10
11 protected:
12 ....;
13
14 };
说明:
- 类是用户自定义的数据类型,不允许对所定义的数据成员初始化,因为其定以后并没有存储空间。 类中定义的数据和函数称为数据成员和函数成员。
- 访问控制属性: 默认定义private权限
公有(public): 声明类的外部接口,即类外部对象可以访问的成员。
私有(private): 只允许与本类成员函数访问;类外部的任何访问都是非法。
保护(protected):和私有类型相似,其差别在于继承过程中对产生的新类访问权限有所不同。
2)对象的定义
1 #include <iostream>
2 class rectangle{
3 private:
4 int w,h;
5 public:
6 void input() {cin>>w,h};
7 int area() {return h*w};
8 };
9
10 void main(void)
11 {
12 rectangle a,b,c;
13 cout<<"请输入第一个矩形的长和宽: ";
14 a.input();
15 cout<<"请输入第二个矩形的长和宽: ";
16 b.input();
17 cout<<"请输入第三个矩形的长和宽: ";
18 c.input();
19 int sum;
20 sum=a.area()+b.area()+c.area();
21 count<<"三个矩形的面积之和为"sum<<endl;
22 }
注意: a. "."操作符用于对象与成员之间; "::" 操作符用于类与其成员之间;
b. 类的封装性---对象中的public、protected成员不允许被非成员函数直接访问。
2. 构造函数和析构函数
1 class Clock
2 {
3 public:
4 Clock(int NewH, int NewM, int NewS); //构造函数
5 void SetTime(int NewH, int NewM, int NewS);
6 void ShowTime();
7 private:
8 int Hour, Minute, Second;
9 };
10
11 构造函数的实现:
12
13 Clock::Clock(int NewH, int NewM, int NewS)
14 {
15 Hour=NewH;
16 Minute=NewM;
17 Second=NewS;
18 }
19
20 建立对象时构造函数的作用:
21
22 int main()
23 {
24 Clock c(0,0,0); //隐含调用构造函数,将初始值作为实参。
25 c.ShowTime();
26 return 0;
27 }
说明: 构造函数---- 在创建对象时,使用给定的值将对象初始化。 在被创建时系统自动调用的函数。
- 与类同名的函数成员称为---构造函数,其作用是为对象初始化。
- 不能指定返回类型(包括void类型)
- 一个类可以定义多个构造函数,可以带参数也可以不带参数;
- 如果类中没有构造函数,那么编译器会自动建立一个无参数的构造函数;
- 对象在创建时构造函数被自动调用
----------------------------析构函数
是对象被释放时,由系统自动调用的函数。 功能---在释放一个对象前,做一系列清理工作。 一般用来做撤销对象进行的清理工作。 如 释放由构造函数分配的内存
以~开头。 特点:
- 在对象撤销时,析构函数被自动调用。
- 没有返回值。
- 不接受任何参数。
- 一个类中,如果没定义析构函数,系统会自动生成一个不做任何事的默认析构函数。 即函数体为空。
-
1 #include <iostream> 2 using namespace std; 3 class relese{ 4 private: 5 int num; 6 float f1; 7 public: 8 relese() { num = 0; f1 = 0.0; } 9 relese(int n, float f) { num = n; f1 = f; } 10 void output() { cout << num << "," << f1 << endl; } 11 ~relese() { cout << "析构函数被调用" << endl; } 12 }; 13 14 void main() 15 { 16 relese x; 17 relese y(4, 5); 18 x.output(); 19 y.output(); 20 }
注: 构造函数和解析函数不需要制定函数类型,也不允许有返回值。 析构函数不需要参数;
构造函数可以重载,而析构函数不允许重载;
构造函数和析构函数都属于成员函数,在类的内部和外部定义均可。
3. 类中的const修饰符
变量或对象经过const修饰后,其值不能被更改-----被const修饰的变量其对象必须进行初始化。
1) 常对象
指对象的数据成员值在对象被调用时,不能被改变。
1 #include <iostream.h> 2 3 class A{ 4 public: 5 A(int i,j;) {x=i;y=j;} 6 void print() const; 7 private: 8 int x,y; 9 }; 10 11 void A::print const 12 {cout<<x<<""<<y<<endl;} 13 14 void main(void) 15 { 16 A const a(3,4); 17 a.print(); 18 a.print(); 19 }
常对象的声明方式:
const <类名> <对象名>
或 <类名> ocnst <对象名>
2). 常成员函数
用const修饰的常成员函数不能更新对象的数据成员,也不能调用普通成员函数。 声明形式如下:
<类型> <函数名> (<参数>) const;
3). 常数据成员
用const修饰的数据成员称之为常数据成员。 任何函数都不能对常数据成员赋值。 构造函数对场数据程艳进行初始化时,也只能通过初始列表来进行。
4. 静态成员
静态成员函数主要用来解决同一个类的不同对象数据之间的数据共享问题。 分为---静态数据成员和静态函数成员。
1) 静态数据成员
- 用static关键字声明数据成员。
- 每一个类只有一个存储单元;该数据成员为该类的所有对象所共有,不属于任何一个对象。
- 静态数据成员初始化 必须在类外进行定义性说明,其一般形式为:
ru static int countP; //声明
int pet::countP=0; //静态数据成员初始化
2)静态函数成员
- 使用static声明的函数成员,为一个类的全部对象所共享,即可以共同维护;
- 对于共有的静态函数,可以通过类名或对象名调用;而一般的非静成员函数只能通过对象名来调用;
- 静态成员函数必须通过对象名来访问非静态数据成员
1 class A 2 { 3 public : 4 static void f(A a); //静态函数声明 5 private: 6 int x; 7 }; 8 9 void A::f(A a) 10 { 11 cout<<x; //对x的引用是错误的 12 cout<<a.x//正确 静态成员函数必须通过对象名来访问非静态数据成员 13 }
5.友元
类的友元可以访问类的所有数据成员(包括私有、和保护成员)。 友元在类之间、类与普通函数之间,共享了内部的数据,但对类的封装性有一定的破坏性。
1 friend float fDist(distance p1,distance p2); //友元函数的声明 2 3 friend float distance ::Dist(distance p1,distance p2); //友元函数的引用
友元类
友元是一个类,即成为友元类。 友元类的所有成员函数都是友元函数。 定义友元类的一般形式为:
friend class <友元类名>;
二. 《C++ Primer》中,第七章中的类