1.类与封装的概念
1.1 类的组合
- 电脑—般而言是由CPU, 内存,主 板,键盘和硬盘等部件组合而成。
1.2 思考
- 学习电脑组装需要多少时间?
- 学习电脑组装是否需要学习显示器,键盘, 鼠标,主板,内存等部件的设计与制造?
1.3 类的封装
- 类通常分为以下两个部分
- 类的实现细节
- 类的使用方式
- 当使用类时,不需要关心其实现细节
- 当创建类时,才需要考虑其内部实现细节
- 例:
- 普通用户使用手机,只需要学习如何发短信,打电话,拍照,等等
- 手机开发工程师, 需要考虑手机内部的实现细节
1.4 封装的基本概念
- 根据经验:并不是类的每个属性都是对外公开的
- 如:女孩子不希望外人知道自己的体重和年龄
- 如:男孩子不希望别人知道自己的身高和收入
- 而一些类的属性是对外公开的
- 如:人的姓名,学历,国籍,等
- 必须在类的表示法中定义属性和行为的公开级别,类似文件系统中文件的权限
1.5 C++中类的封装
- 成员变量: C++中用于表示类属性的变量
- 成员函数: C++中用于表示类行为的函数
- C++中可以给成员变量和成员函数定义访问级别
- public:成员变量和成员函数可以在类的内部和外界访问和调用
- private:成员变量和成员函数只能在类的内部被访问和调用
#include <stdio.h>
struct Biology
{
bool living;
};
struct Animal : Biology
{
bool movable;
void findFood()
{
}
};
struct Plant : Biology
{
bool growable;
};
struct Beast : Animal
{
void sleep()
{
}
};
struct Human : Animal
{
void sleep()
{
printf("I'm sleeping...\n");
}
void work()
{
printf("I'm working...\n");
}
};
struct Girl : Human
{
private:
int age;
int weight;
public:
void print()
{
age = 22;
weight = 48;
printf("I'm a girl, I'm %d years old.\n", age);
printf("My weight is %d kg.\n", weight);
}
};
struct Boy : Human
{
private:
int height;
int salary;
public:
int age;
int weight;
void print()
{
height = 175;
salary = 9000;
printf("I'm a boy, my height is %d cm.\n", height);
printf("My salary is %d RMB.\n", salary);
}
};
int main()
{
Girl g;
Boy b;
g.print();
b.age = 19;
b.weight = 120;
//b.height = 180;
b.print();
getchar();
return 0;
}
- 运行结果
1.5 类成员的作用域
- 类成员的作用域都只在类的内部,外部无法直接访问
- 成员函数可以直接访问成员变量和调用成员函数
- 类的外部可以通过类变量访问public成员
- 类成员的作用域与访问级别没有关系
- C++中用struct定义的类中所有成员默认为public
2. class的引入
- 经过不停的改进,结构体struct变得越来越不像它在C语言中的样子了!!!
- 类的关键字
- struct在C语言中已经有了自己的含义,必须继续兼容
- 在C++中提供了新的关键字class用于类定义
- class和struct的用法是完全相同的
- 在用struct定义类时,所有成员的默认访问级别为public
- 在用class定义类时,所有成员的默认访问级别为private
#include <stdio.h>
struct A
{
// defualt to public
int i;
// defualt to public
int getI()
{
return i;
}
};
class B
{
// defualt to private
int i;
// defualt to private
int getI()
{
return i;
}
};
int main()
{
A a;
B b;
a.i = 4;
printf("a.getI() = %d\n", a.getI());
b.i = 4; //error
printf("b.getI() = %d\n", b.getI()); //error
return 0;
}
3.一个运算类的实现
- 需求:开发—个用于四则运算的类
- 提供setOperator函数设置运算类型
- 提供setParameter函数设置运算参数
- 提供result函数进行运算
- 其返回值表示运算的合法性
- 通过引用参数返回结果
- 类的真正形态
- C++中的类支持声明和实现的分离
- 将类的实现和定义分开
- .h头文件中只有类的声明 :成员变量和成员函数的声明
- .cpp源文件中完成类的其它实现 :成员函数的具体实现
- 对于使main函数来说,只需要知道怎么使用Operator即可,没有必要知道其实现
- 解决方案:
- Operator.h头文件中只有类的声明
- Operator.cpp中完成类的其它实现
- Operator.h
#ifndef _OPERATOR_H_
#define _OPERATOR_H_
class Operator
{
private:
char mOp;
double mP1;
double mP2;
public:
bool setOperator(char op); // 设置运算类型
void setParameter(double p1, double p2); // 设置运算参数
bool result(double &r); // 进行运算
};
#endif
- Operator.cpp
#include "Operator.h"
bool Operator::setOperator(char op)
{
bool ret = false;
if( (op == '+') || (op == '-') || (op == '*') || (op == '/') )
{
ret = true;
mOp = op;
}
else
{
mOp = '\0';
}
return ret;
}
void Operator::setParameter(double p1, double p2)
{
mP1 = p1;
mP2 = p2;
}
bool Operator::result(double &r)
{
bool ret = true;
switch( mOp )
{
case '/':
if( (-0.000000001 < mP2) && (mP2 < 0.000000001) )
{
ret = false;
}
else
{
r = mP1 / mP2;
}
break;
case '+':
r = mP1 + mP2;
break;
case '*':
r = mP1 * mP2;
break;
case '-':
r = mP1 - mP2;
break;
default:
ret = false;
break;
}
return ret;
}
- main.cpp
#include <stdio.h>
#include "Operator.h"
int main(int argc, char *argv[])
{
Operator op;
double r = 0;
op.setOperator('/');
op.setParameter(8, 2);
if( op.result(r) )
{
printf("Result is %f\n", r);
}
else
{
printf("Error!\n");
}
printf("Press any key to continue...");
getchar();
return 0;
}
4.小结
- 类的精华在于封装
- 将实现细节和使用方式相分离
- C++中通过public和private实现类的封装
- public成员可以通过变量被外界访问
- private成员只能够在类内部使用
- 类的定义和实现可以分开到不同的文件中