C++封装向量-线性表

封装前的考虑

在C++中有很丰富的库,当属STL模板,STL的设计和优化都为我们提供了应有的功能。然而对于新手而言,尝试进行一个封装,会使得自己更加熟悉面向对象。

面向对象三大特性:封装、继承、多态。这也是面向对对象语言相对面向过程而言,最大的优势和特点。面向对象使得程序更加利于维护,让设计人员更加关注设计,要想真正的理解面向对象的特性,则必须要清楚和掌握这三大规律。

在C++中,STL提供了Vector类,表示向量,其本质则是线性表的实现,并且可以在内部实现自动扩容,并且借助迭代器,可以很方便很快速的对表中元素进行访问和遍历。

因此我们手动封装的线性表,可以有以下的功能:

  1. 自动扩容
  2. 迭代器访问元素
  3. 下标式快速访问元素值
  4. 移除元素
  5. 增加元素
  6. 长度管理

上述这些功能,都是需要一个向量所需要提供的功能,并且基于面向对象的设计而言,采用迭代器模式的设计,可以很好的减小容器对象与数据之间的紧密耦合,通过迭代器去遍历向量表,可以很大程度的增加遍历的安全性和便利性。

在该设计中,可进行三个类的设计: Sequeence 抽象基类,ZArray类,Iterator 抽象基类, ZArrayIterator类,其中两个抽象基类中分别提供了序列类的基本操作,增删查改等,Iterator基本定义了迭代器的方法接口,可以很好的实现多态,并且可以拥有很好的扩展性,因为对序列数据容器而言,其逻辑结构可以是连续的向量式的,也可以是链式的,由此他们之间的遍历方式都不同,访问方式也不同,因此为了可扩展性,可以进行抽象,使得迭代器和序列容器进行交互,而无需使用具体的子类,并且可以很好的进行扩展。那么在这里,面向对向的特性则充分包含了进去,封装是完好类设计的基础,继承则是扩展的必经之路,多态则是在面向抽象编程的基础。


值得注意的是,由于在C++中容器类都采用模板的方式去进行封装,由此需要注意的是,最好将.h的定义和.cpp的定义为一个文件中,否则在某些编译环境中可能造成link错误!

学会如何去抽象

  • 首先我们进行Sequence类的抽象定义
//
//  Sequence.hpp
//  Array
//
//  Created by 邹智鹏 on 16/7/3.
//  Copyright © 2016年 Frank. All rights reserved.
//

#ifndef Sequence_hpp
#define Sequence_hpp

#include <stdio.h>
#include "Iterator.hpp"

namespace ZTemplate {

    typedef unsigned int z_size;    // 用于表示大小,为无符号整形
    typedef long rank;              // 用于表示秩
    template<class T>
    class Sequence {
   
    public:
        /**
         * 定义函数指针,用于表示两个值的比较, 若两个值相等,返回0,若val1 > val2 返回1, 否则返回-1
         */
        typedef int (*__FUNC_COMPARE_)(const T &val1, const T &val2);
        /**
         * 插入到最后一个位置
         */
        virtual void push_back(const T& val) = 0;
        /**
         * 从指定位置中,移除元素,并返回该元素的副本,若为指针,请自行进行内存管理
         * @param pos 元素位置
         * @return 返回该元素值
         */
        virtual T pop(const rank pos) = 0;
        /**
         * 访问指定位置的值
         * @param pos 元素所在的位置
         * @return 返回该位置的元素值
         */
        virtual const T &at(const rank pos) const = 0;
        /**
         * 移除指定位置元素
         * @param pos 元素所在位置
         * @return 返回是否移除成功
         */
        virtual bool remove(const rank pos) = 0;
        /**
         * 根据指定值,在序列中进行查找,若查找到符合条件的则进行移除
         */
        virtual bool remove(T &val1, __FUNC_COMPARE_ compare);

        /**
         * 获取迭代器
         * @return 返回迭代器
         */
        virtual Iterator<T> &iterator() = 0;
        /**
         * 重载访问器
         * @param pos 元素位置
         * @return 返回元素引用
         */
        virtual T& operator[](const rank pos) = 0;
    protected:
    };
}

template<class T>
bool ZTemplate::Sequence<T>::remove(T &val1, __FUNC_COMPARE_ compare) {
    Iterator<T> &curIterator = iterator();  // 获取到迭代器实例
    bool found = false;
    rank i = 0; // 秩
    while (!found && curIterator.hasNext()) {
        if (compare(val1, curIterator.data()) == 0) {
            // 两者值相等
            found = t
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值