文章目录
生活中的封装
学习电脑组装是否需要学习显示器,键盘,鼠标,主板,内存等部件的设计与制造?
类的封装
类通常分为以下两个部分
类的实现细节
类的使用方式
当使用类时,不需要关心其实现细节
当创建一个类时,才需要考虑其内部实现细节
例:
使用手机时,只需要知道如何发短信,打电话,拍照等等即可,不需要关心手机是如何开发出来的。
手机开发工程师就需要考虑手机内部的实现细节,如硬件细节和软件细节。
封装的基本概念
根据日常生活中的经验:并不是类的每个属性都是对外公开的
如:女孩子不希望外人知道自己的年龄和身高
如:一些男孩子不希望别人知道自己会尿床
而一些类的属性是对外公开的
如:人类的姓名,学历,国籍等
因此,需要在类的表示法中定义属性和行为的公开级别
类似文件系统中文件的权限
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() //睡觉 //struct中默认是public的
{
printf("I'm sleeping...\n");
}
void work() //行动
{
printf("I'm working...\n");
}
};
struct Girl : Human //女孩
{
private:
int age;
public:
void play()
{
printf("I'm girl, I'm playing...\n");
}
void print()
{
age = 22; //类的内部
printf("Girl's age is %d\n", age);
play(); //类的内部
sleep();
work();
}
};
struct Boy : Human //男孩
{
public:
int age;
void play()
{
printf("I'm boy, I'm playing...\n");
}
void print()
{
age = 23;
printf("Boy's age is %d\n", age);
play();
sleep();
work();
}
};
int main(int argc, char *argv[])
{
Girl girl;
girl.print(); //类的外部
Boy boy;
boy.print();
printf("Press any key to continue...");
getchar();
return 0;
}
类成员的作用域
类成员的作用域都只在类的内部,外部无法直接访问
成员函数可以直接访问成员变量和调用其它成员函数
类的外部可以通过类变量访问public成员
类成员的作用域与访问级别没有关系
tips:
C++中用struct定义的类的所有成员默认为public
#include <stdio.h>
int i = 1;
struct Test
{
private:
int i; //类似:C语言中局部变量覆盖全局变量
//i的作用域在struct{ }之间
public:
int j;
int getI()
{
i = 3;
return i;
}
};
int main()
{
int i = 2; // C语言中局部变量覆盖全局变量
Test test;
test.j = 4;
printf("i = %d\n", i); // C语言中局部变量覆盖全局变量
printf("::i = %d\n", ::i); //默认空间
//printf("test.i = %d\n", test.i);
printf("test.j = %d\n", test.j);
printf("test.getI() = %d\n", test.getI()); //类似:C语言中局部变量覆盖全局变量
printf("Press any key to continue...");
getchar();
return 0;
}
struct变得越来越不像它在C中的样子了!!!
类的真正形态
struct在C语言中已经有了自己的含义,只能继续兼容
在C++中提供了新的关键字class用于类定义
class和struct的用法是完全相同的
class和struct有什么区别?
在用struct定义类时,所有成员的默认属性为public
在用class定义类时,所有成员的默认属性为private
#include <stdio.h>
struct A
{
int i; //Default to public
int getI() //Default to public
{
return i;
}
};
class B
{
int i; //Defult to private
int getI() //Defult to private
{
return i;
}
};
int main(int argc, char *argv[])
{
A a;
B b;
a.i = 1;
a.getI();
b.i = 2;
b.getI();
printf("Press any key to continue...");
getchar();
return 0;
}
实例代码:一个运算类的实现
#include <stdio.h>
class Operator
{
public:
bool setOperator(char op)
{
bool ret = false;
if( (op == '+') || (op == '-') || (op == '*') || (op == '/') )
{
ret = true;
m_op = op;
}
else{
m_op = ' ';
}
return ret;
}
void setPar(double p1, double p2)
{
m_p1 = p1;
m_p2 = p2;
}
bool result(double& r)
{
bool ret = true;
switch(m_op)
{
case '/':
if( (-0.0000001 < m_p2 ) && ( m_p1 < 0.0000001 ) ) //被除数不能为0 定义精度
{
ret = false;
}
else
{
r = m_p1/m_p2;
}
break;
case '+':
r = m_p1+m_p2;
break;
case '-':
r = m_p1-m_p2;
break;
case '*':
r = m_p1*m_p2;
break;
defalut:
ret = false;
break;
}
return ret;
}
private:
char m_op;
double m_p1;
double m_p2;
};
int main(int argc, char *argv[])
{
Operator op;
double r;
op.setOperator('a');
op.setPar(8.0, 2.0);
if(op.result(r)){
printf("Result is %f\n", r);
}
printf("Press any key to continue...");
getchar();
return 0;
}
运算类的改进
在Operator中所有成员函数的实现都在类中完成
问题:对于使main函数来说,只需要知道怎么使用Operator即可,没有必要知道其实现
解决方案:将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, 4);
if( op.result(r) )
{
printf("Result is %f\n", r);
}
printf("Press any key to continue...");
getchar();
return 0;
}
小结
类的精华在于封装
将实现细节和使用方式相分离
C++中通过public和private实现类的封装
public成员可以通过变量被外界访问
private成员只能够在类内部使用
类的定义和实现可以分开到不同的文件中