【无标题】


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

首先使用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;
}

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值