IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 【无标题】 -> 正文阅读

[C++知识库]【无标题】


从一个实例看数据抽象与封装

首先使用C语言的方式来实现


#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
struct Link
{
	int data;
	struct Link* next;
};

struct Stack
{
	struct Link* head;
	int size;
};
void StackInit(struct Stack* stack)//栈的初始化
{
	stack->head = NULL;
	stack->size = 0;
}
void StackPush(struct Stack* stack, const int data)//入栈的操作
{
	struct Link* node;
	node = (struct Link*)malloc(sizeof(struct Link));
	assert(node != NULL);
	node->data = data;
	node->next = stack->head;
	stack->head = node;
	++stack->size;
}
//判定栈是否是空的
int StackEmpty(struct Stack* stack)
{
	return (stack->size == 0);
}
int  StackPop(struct Stack* stack, int* data)
{
	if (StackEmpty(stack))
	{
		return 0;//栈为空不能够进行出栈操作,返回0
	}
	struct Link* tmp = stack->head;
	*data = stack->head->data;
	stack->head = stack->head->next;
	free(tmp);
	--stack->size;
	return 1;
}
void StackCleanup(struct Stack* stack)
{
	struct Link* tmp;
	while (stack->head)
	{
		tmp = stack->head;
		stack->head = stack->head->next;
		free(tmp);
	}
	stack->size = 0;
}
int main(void)
{
	struct Stack stack;
	StackInit(&stack);
	int i;
	for (i = 0; i < 5; i++)
	{
		StackPush(&stack, i);
	}
	while (!StackEmpty(&stack))
	{
		StackPop(&stack, &i);
		printf("%d", i);
	}
	printf("\n");
	return 0;
}

使用C++语言实现

#include<iostream>
using namespace std;

class Stack//在C++中把栈封装成类,提供相应的方法
{
	struct Link {
		int data_;
		Link* next_;
		Link(int data, Link* next) :data_(data), next_(next)
		{
		}
	};
public:
	Stack() :head_(0),size_(0)
	{

	}
	~Stack()
	{
		Link* tmp;
		while (head_)
		{
			tmp = head_;
			head_ = head_->next_;
			delete tmp;
		}
	}
	void Push(const int data)
	{
		Link* node = new Link(data, head_);
		head_ = node;
		++size_;
	}
	bool Empty()
	{
		return(size_ == 0);
	}
	bool Pop(int& data)
	{
		if (Empty())
		{
			return false;
		}
		Link* tmp = head_;
		data = head_->data_;
		head_ = head_->next_;
		delete tmp;
		--size_;
		return true;

	}
	void StackInit(struct Stack* stack)
	{
		stack->head_ = NULL;
		stack->size_ = 0;
	}
private:
	Link* head_;
	int size_;
};

int main(void)
{
	 Stack stack;
	int i;
	for (i = 0; i < 5; i++)
	{
		stack.Push(i);
	}
	while(!stack.Empty())
	{
		stack.Pop( i);
		cout << i << " ";
	}
	cout << endl;
	return 0;
}
  • 对比发现C++栈的初始化构造函数中实现,空间释放在析构函数中实现
  • C++每个函数的调用方式都不用传递地址
  • 优势:避免名称冲突 类型的扩充 数据的封装能够保护内部的数据不遭受外界的破坏

友元介绍:

友元是一种允许非类成员函数访问类的非公有成员的一种机制。

可以把一个函数指定为类的友元,也可以把整个类指定为另一个类的友元。
1.友元函数
2.友元类

友元函数在类的作用域外定义,需要在类体中进行说明。友元函数是为了提高程序的运行效率

//友元实例
#include<iostream>
#include<math.h>
using namespace std;
class Point
{
	friend double Distance(const Point& p1, const Point& p2);//Point的友元函数,但不是成员函数
public:
	Point(int x, int y);
private:
	int x_;
	int y_;
};
Point::Point(int x, int y) :x_(x), y_(y)
{

}
double Distance(const Point& p1, const Point& p2)
{
	double dx = p1.x_-p2.x_;
	double dy = p1.y_-p2.y_;//友元函数破坏了类的封装性

	return sqrt(dx*dx+dy*dy);//友元函数的定义在类体外
}
int main(void) 
{
	Point p1(3, 4);
	Point p2(6, 8);
	cout << Distance(p1, p2) << endl;

	return 0;
}

友元函数注意:

1.友元函数不是类的成员函数,在函数中访问对象的成员,必须用对象名加运算符“.”加对象成员名。但
友元函数可以访问类中所有成员,一般函数只能访问类中的公有成员。
2.友元函数不受类中的访问权限关键字的限制。(放在哪里都无所谓)
3.某类的友元函数的作用域并非该类作用域。如果该友元函数是另一个类的成员函数,则用其作用域为另一类的作用域
4.友元函数破坏了面向对象程序设计的封装性,所以友元函数如果不是必须使用,尽可能少用。

#include<iostream>
using namespace std;//电视机和遥控的例子

class Television
{
friend class TeleController;
public:
	Television(int volume,int chanel):volume_(volume),chanel_(chanel)
		{

		}
private:
	int volume_;
	int chanel_;
};
class TeleController
{
public:
	void VolumeUp(Television& tv)
	{
		tv.volume_ += 1;//不允许访问私有成员
	}
	void VolumeDown(Television& tv)
	{
		tv.volume_ -= 1;
	}
	void ChanelUp(Television& tv)
	{
		tv.chanel_ += 1;
	}
	void ChanelDown(Television& tv)
	{
		tv.chanel_ -= 1;
	}
};
int main(void)
{
	Television tv(1, 1);
	TeleController tc;
	tc.VolumeUp(tv);
	return 0;
}

友元关系是单向的;友元关系是不能被传递的;友元关系不能被继承;地处理数据的函数和方法。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章           查看所有文章
加:2021-12-07 11:51:13  更:2021-12-07 11:53:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 10:36:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码