C++进阶剖析(八)之封装

1.1封装基本思考
1.1.1 思考

  1. 学习电脑组装需要多少时间?
  2. 学习电脑组装是否需要学习显示器,键盘,鼠标,主板,内存等部件的设计和制造?

1.1.2 类通常分为以下两个部分

  1. 类的实现细节
  2. 类的使用方式
  • 开发者需要考虑类的具体实现细节,而使用者只需要考虑这个类的使用方式。
    • 例如
    • 普通用户使用手机 :只需要学习如何发短信,打电话,拍照等
    • 手机开发工程师 需要考虑手机内部的实现细节
      在这里插入图片描述

1.2 封装的基本概念

1.2.1 概念

  • 根据经验 : 并不是类的每个属性都是对外公开的
    • 如男孩不希望别人知道自己的身高和收入
    • 女孩不希望外人知道自己的体重和年龄
  • 而一些类的属性是对外公开的
    • 如: 人的姓名,学历,国籍
  • 必须在类的表示法中定义属性和行为的公开级别
    • 类似文件系统中文件的权限

1.2.2 C++中类的封装

  • 成员变量 : C++ 中用于表示类属性的变量
  • 成员函数: C++中用于表示类行为的函数
  • C++中可以给成员变量和成员函数定义访问级别
    • public 成员变化和成员函数可以在类的内部和外界访问和调用
    • private成员变化和成员函数只能在类的内部被访问和调用

1.2.3 举例

struct Girl
{
private:
	int age;
	int weight;
public:
	void print()
	{
		age =22;
		weight =50;
		printf("I'm a girl ,I'm %d years old\n",age);
		printf("My weight is %d kg\n",weight);
	}
};
struct Boy
{
private:
	int height;
	int salary;
public:
	int age;
	int weight;
	void print()
	{
		height = 175;
		salary  =5000;
		printf("I'm a boy ,my height is %d\n",height);
		printf("My salary is %d RMB \n",salary);
	}
};

int main()
{
	Girl g;
	Boy b;
	// printf("g.age =%d\n",g.age); //error // age is private
	g.print();
	b.age = 25;  //ok
	// printf("b.height = %d\n",b.height);  //int Boy::height is private
	b.print();
	return 0;
}

1.3 类成员的作用域

1.3.1类成员的作用域

  • 类成员的作用域都只在类的内部,外部无法直接访问

  • 成员函数可以直接访问成员变化和调用成员函数

  • 类的外部可以通过类变量范围public成员(包括成员变量成员函数

  • 类成员的作用域与访问级别没有关系。访问级别是限制外部的类或者函数访问的时候的限制,在类的内部是没有限制的

    • C++中用struct 定义的类中所有成员默认为public

1.3.2 举例子

int i = 1;
struct Test
{
private:
	int i;
public:
	int j;
	int getI()
	{
		i  =10;
		return i;
	}
};
int main()
{
	int i =2;
	Test test;
	test.j =4;
	printf("i=%d\n",i);
	printf("::i=%d\n",::i);   //importance
	printf("test.j =%d\n",test.j);
	//printf("test.i =%d\n",test.i);  //error   “Test::i”: 无法访问 private 成员(在“Test”类中声明)

	printf("test.getI() =%d\n",test.getI());
	return 0;
}

结果:
在这里插入图片描述
类的外部要想访问类的成员变量和成员函数必须通过类的对象来进行访问(静态成员变量和成员函数除外),但是能否访问成功还需要看类的成员的访问级别(public 和private)

1.4 类的真正形态
1.4.1 问题
经过不停的改进,结构体struct变得越来越不行它在C语言中的样子?

  • stuct 在C语言中已经有了自己的含义,必须继续兼容
  • 在C++中提供了新的关键字class用于类定义
  • class和 struct 的用法是完成相同的。

1.4.2 class 和 struct 有什么区别

  • 在用struct定义类时,所有称呼的默认访问级别为public
  • 在用class定义类时,所有成员的默认访问级别为private

1.4.3 案例

struct A
{
	int i;
	int getI()
	{
		return i;
	}
};

class B
{
	int i;
	int getI()
	{
		return i;
	}
};
int main()
{
	A a;
	B b;
	a.i =4;
	printf("a.getI() =%d\n",a.getI());

	//b.i = 5;							//B::i”: 无法访问 private 成员
	//printf("b.getI() =%d\n",b.getI()); //error C2248: “B::getI”: 无法访问 private 成员

	return 0;
}

1.5 开发面向对象实例
1.5.1 需求

  • 需求:开发一个用于四则运算的类
  • 提供setOperator 函数设置运算类型
  • 提供setParameter函数设置运算参数
  • 提供result函数进行运算
    • 返回值表示运算的合法性
    • 通过引用参数返回运算结果

1.5.2 实例代码
CalCulator1.h文件

#include <stdio.h>
#include <stdlib.h>
class CalCulator1
{
private:
	double m_a;
	double m_b;
	char m_oper;
public:
	void setOperator(char oper);
	void setParameter(double a,double b);
	bool result(double &value);
};

CalCulator1.cpp文件

#include "CalCulator1.h"

void CalCulator1::setOperator(char oper)
{
	switch (oper){
		case  '+':	m_oper = '+' ; break;
		case  '-':	m_oper = '-';  break;
		case  '*':	m_oper = '*';  break;
		case  '/':	m_oper = '/';  break;
		default: m_oper = '+' ; break;
	}
}
void CalCulator1::setParameter(double a,double b)
{
	m_a  =a;
	m_b = b;
}
bool CalCulator1::result(double &value)
{
	switch (m_oper){
		case  '+':
			value = m_a + m_b ;
			break;
		case  '-':	
			value = m_a - m_b; 
			break;
		case  '*':	
			value = m_a * m_b; 
			break;
		case  '/':	
			value = m_a / m_b;  
			break;
		default: 
			value = m_a + m_b ;
			break;
	}
	printf("Test m_oper=[%c]\n",m_oper);
	printf("Test value=%d\n",value);
	return true;

}

main.cpp

int main()
{
	CalCulator1 cal;
	double value =0;
	cal.setOperator('+');
	cal.setParameter(10,5);
	cal.result(value);
	printf("value =%lf\n",value); 
	printf("value =%d\n",value);  //error  
	return 0;
}

在这里插入图片描述
问题原因 :

printf(“value =%d\n”,value); 正常的结果应该是15.0000
可是在Linux中打印一个负数 -837201920
在VS2008中打印 0 ;
终于找到了原因,是因为函数result(double &value) 参数是double类型,打印输出的时候是%d,所以打印出错误的数据,这和int型数据和double型数据在内存中的存储方式不同有关。

参考一 : 狄泰软件课程

如有侵权:请联系邮箱 1986005934@qq.com

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值