当前位置: 首页 > news >正文

网站ip地址范围网络上市场推广

网站ip地址范围,网络上市场推广,哈尔滨网站建设培训学校,网站上地图是怎样做的往期内容回顾 Queue介绍和使用 Stack介绍和使用 String, Vector, List 复习 List类型的自实现 List类型(初识) Vector类的自实现 Vector类(注意事项) 初识Vector String类的自实现 String类的使用(续) …

 往期内容回顾  

           Queue介绍和使用  

           Stack介绍和使用

           String, Vector, List 复习

           List类型的自实现

          List类型(初识)

          Vector类的自实现

         Vector类(注意事项)

          初识Vector

          String类的自实现

         String类的使用(续)  

         String类(续)

         String类(初识)


C++ 容器适配器自实现(Stack & Queue)

前言

        在掌握了 string、vector(连续内存)、list(节点容器)之后,我们再看 栈(Stack) 与 队列(Queue) 会更容易:它们在 STL 中并不是“容器”,而是 容器适配器(Container Adapter)——基于一个可用作底层的顺序容器,只暴露特定的接口与语义

 Stack(栈):后进先出(LIFO)

典型操作:push、pop、top

 Queue(队列):先进先出(FIFO)

典型操作:push、pop(从头弹)、front、ba

标准库默认用 deque 作为底层,因为它的双端插删性能均衡。本文将从零实现 my_stack 与 my_queue,并解释设计取舍、异常安全、迭代器失效与可替换底层容器的约束。


主要内容

  1. 1、适配器思想与底层容器约束

  2. 2、my_stack:接口、约束、实现与测试

  3. 3、my_queue:接口、约束、实现与测试

  4. 4、复杂度、异常安全、迭代器/引用有效性

  5. 5、可替换底层容器:deque vs vector vs list

  6. 6、常见坑位与工程化建议

  7. 总结:为何“用组合而非继承”


一、适配器思想与底层容器约束

适配器的核心:不自己管理存储,只组合一个“底层容器”,并将接口受限为“栈语义/队列语义”。

这要求底层容器满足最小能力集合接口约束):

  • Stack 底层容器需要

    back() / push_back() / pop_back() / empty() / size()

    (典型可用:deque<T>、vector<T>、list<T>)

  • Queue 底层容器需要

    front() / back() / push_back() / pop_front() / empty() / size()

    (典型可用:deque<T>、list<T>;vector<T> 不可用 —— 没有 pop_front())

标准库 std::stack/std::queue 默认 deque<T>,也允许自定义容器,只要满足上述接口。

二、my_stack 的实现

2.1 设计要点

  • 按标准库风格提供:top / push / emplace / pop / empty / size / swap

  • 不提供迭代器与遍历接口(保持“栈语义”的束缚)

  • 接口时间复杂度与异常安全以底层容器为准

  • 采用组合(一个成员 Container _con;)


2.2 代码(C++14+ 版本,适配 

deque/vector/list)

#include <deque>
#include <utility>
#include <type_traits>template<class T, class Container = std::deque<T>>
class my_stack {
public:using value_type      = T;using container_type  = Container;using size_type       = typename Container::size_type;using reference       = typename Container::reference;using const_reference = typename Container::const_reference;my_stack() = default;explicit my_stack(const Container& cont)  : c_(cont) {}explicit my_stack(Container&& cont)       : c_(std::move(cont)) {}bool empty() const noexcept { return c_.empty(); }size_type size() const noexcept { return c_.size(); }reference       top()       { return c_.back(); }const_reference top() const { return c_.back(); }void push(const value_type& v)  { c_.push_back(v); }void push(value_type&& v)       { c_.push_back(std::move(v)); }template<class... Args>decltype(auto) emplace(Args&&... args) {return c_.emplace_back(std::forward<Args>(args)...);}void pop() { c_.pop_back(); }void swap(my_stack& other)noexcept(noexcept(std::swap(c_, other.c_))) {using std::swap;swap(c_, other.c_);}private:Container c_;
};

2.3 快速测试

#include <vector>
#include <list>
#include <iostream>int main() {my_stack<int> s1;                 // 默认 deques1.push(1); s1.push(2); s1.push(3);std::cout << s1.top() << "\n";    // 3s1.pop();std::cout << s1.top() << "\n";    // 2my_stack<int, std::vector<int>> s2; // vector 也可作 Stack 底层s2.emplace(42);std::cout << s2.top() << "\n";    // 42my_stack<int, std::list<int>> s3;   // list 也可作 Stack 底层s3.push(7);std::cout << s3.top() << "\n";    // 7
}

三、my_queue的实现

3.1 设计要点

  • 按标准库风格提供:front / back / push / emplace / pop / empty / size / swap

  • 不提供迭代器与遍历接口(保持“队列语义”的束缚)

  • 底层容器必须支持 push_back / pop_front,这决定了 vector 不可用


3.2 代码(C++14+ 版本,默认 deque,也支持 list)

#include <deque>
#include <utility>template<class T, class Container = std::deque<T>>
class my_queue {
public:using value_type      = T;using container_type  = Container;using size_type       = typename Container::size_type;using reference       = typename Container::reference;using const_reference = typename Container::const_reference;my_queue() = default;explicit my_queue(const Container& cont)  : c_(cont) {}explicit my_queue(Container&& cont)       : c_(std::move(cont)) {}bool empty() const noexcept { return c_.empty(); }size_type size() const noexcept { return c_.size(); }reference       front()       { return c_.front(); }const_reference front() const { return c_.front(); }reference       back()        { return c_.back(); }const_reference back() const  { return c_.back(); }void push(const value_type& v)  { c_.push_back(v); }void push(value_type&& v)       { c_.push_back(std::move(v)); }template<class... Args>decltype(auto) emplace(Args&&... args) {return c_.emplace_back(std::forward<Args>(args)...);}void pop() { c_.pop_front(); }void swap(my_queue& other)noexcept(noexcept(std::swap(c_, other.c_))) {using std::swap;swap(c_, other.c_);}private:Container c_;
};

3.3 快速测试

#include <list>
#include <iostream>int main() {my_queue<int> q;                 // 默认 dequeq.push(10); q.push(20); q.emplace(30);std::cout << q.front() << "," << q.back() << "\n"; // 10,30q.pop();std::cout << q.front() << "\n"; // 20my_queue<int, std::list<int>> ql; // list 可用作 Queue 底层ql.push(1); ql.push(2); ql.pop();std::cout << ql.front() << "\n";  // 2
}

四、复杂度、异常安全、迭代器/引用有效性

4.1 时间复杂度(以默认 deque为参考)

  • Stack:push/pop/top/empty/size → O(1)

  • Queue:push/back/front/pop/empty/size → O(1)

极少数情况下 deque 内部重分配可能引起常数因子的波动,但外部语义仍视作常数时间。

4.2 异常安全

  • push/emplace 可能在分配或构造时抛异常;容器保持自洽,要么成功插入,要么回滚到插入前状态(依赖底层容器保障)。

  • pop 不抛异常(但对空容器调用是未定义行为,建议在 Debug 下断言/检查)。

4.3 迭代器/指针/引用的有效性(适配器本身不暴露迭代器)

  • top()/front()/back() 返回的引用在元素被 pop 后立即失效

  • push 是否使已有引用失效取决于底层容器

  • deque:在极少数扩容/重组时,引用/指针可能失效;

    list:节点稳定,绝大多数情况下引用有效(被删节点除外)。

结论:尽快使用 top()/front() 返回的引用,不要长期持有。


五、可替换底层容器:该怎么选?

适配器

推荐默认

备选

说明

Stack

deque<T>

vector<T>/list<T>

三者都能满足 Stack 的需求

Queue

deque<T>

list<T>

不要用 vector,缺 pop_front()

  • deque:两端操作均衡、实现成熟、整体吞吐好 → 首选

  • vector(仅 Stack):push_back/pop_back/top 很快;但随机插入/头删不适合

  • list:指针/引用稳定、频繁中间插删友好,但节点开销大、局部性差


六、常见坑位与工程化建议

  1. 不要继承底层容器

    适配器语义是“约束接口”,用组合而非继承;继承会把不该暴露的接口也暴露出来,破坏 LIFO/FIFO 语义边界。

  2. 不提供 clear() 是否合适?

    标准 std::stack/queue 不提供 clear();

    需要清空时可:while(!s.empty()) s.pop(); 或 my_stack<T>().swap(s);。

    自定义适配器可以“加一个 clear()”作为工程便捷,但要清楚与标准差异

  3. 空容器上的 top()/front()/back()/pop()

    与标准一致:未定义行为。工程里可在 Debug 宏下 assert(!empty()) 防御。

  4. emplace 的价值

    复杂对象构造时,emplace 原地构造避免一次拷贝/移动,异常安全更自然。

  5. 线程安全

    适配器/底层容器都不是线程安全;并发场景须加锁或使用并发队列。

  6. C++20 Concepts(可选)

    你可以用 Concepts 对底层容器做编译期约束,让错误更早暴露(见下)。


七、(可选)用 C++20 Concepts 约束底层容器

#if __cpp_concepts
#include <concepts>template<class C, class T>
concept StackContainer = requires(C c, T v) {{ c.back() } -> std::same_as<typename C::reference>;{ c.push_back(v) };{ c.pop_back() };{ c.empty() } -> std::same_as<bool>;{ c.size() };
};template<class C, class T>
concept QueueContainer = requires(C c, T v) {{ c.front() } -> std::same_as<typename C::reference>;{ c.back()  } -> std::same_as<typename C::reference>;{ c.push_back(v) };{ c.pop_front() };{ c.empty() } -> std::same_as<bool>;{ c.size() };
};// 用法:template<class T, StackContainer<T> Container = std::deque<T>> class my_stack { ... };
#endif

这能让「把 vector 错误地拿去做 queue 底层」直接编译失败,错误更易懂。


总结

  • Stack/Queue 是“适配器”,不是容器:通过组合底层容器并收窄接口来提供 LIFO/FIFO 语义。

  • 关键在接口约束

    • Stack 需 back/push_back/pop_back;

    • Queue 需 front/back/push_back/pop_front;

      因此 Queue 不能用 vector。

  • 复杂度与异常安全 取决于底层容器;默认 deque 综合表现最好。

  • 迭代器/引用有效性:适配器不提供迭代器;front()/top() 的引用在 pop 后失效,push 的影响以底层容器为准。

  • 工程建议:用组合而非继承;可在 Debug 下断言空栈/空队列的错误;必要时使用 Concepts 约束。

  • 学习意义:通过自实现适配器,你会更透彻地理解 STL 的“以语义约束能力”的设计思想,以及组合优于继承的工程实践。

http://www.dtcms.com/a/529558.html

相关文章:

  • 2025年江西省职业院校技能大赛“大数据应用与服务”竞赛样题
  • 排名好的手机网站建设电商软件平台开发
  • 万网网站建设万网网站建设建设银行钓鱼网站
  • 晨光文具网站建设策划书网站实时显示
  • 【Java高级编程】集合框架和泛型
  • 雅菲奥朗人工智能知识墙分享(二):『AI数据:人工智能时代的“数字燃料”——数据是AI的“第一生产力”』
  • 智能电网建设对就业市场有何影响?
  • 【08】C语言数据类型--字符类型
  • 张家界公司网站建设wordpress 新浪图片
  • 枣庄高端品牌网站建设案例微信上修改wordpress
  • 第十八讲(一) 三重积分
  • 怎么建设一个营销型网站博罗营销网站制作
  • 网站开发完整视频合肥网络推广有限公司
  • 第7章树和二叉树:二叉树遍历算法的应用
  • Marvell TX9190 Liquid-Cooled CPO Switch
  • 怎样做后端数据传输前端的网站asp汽车销售公司网站源码 4s店网站源码 汽车网站建设 完整无
  • oa网站建设推广吉林网站建设电话
  • 网站推广双鼎微信小程序可以做音乐网站吗
  • AI决策vs人工决策:效率的底层逻辑与选择边界
  • 合肥网站建设方案优化wordpress页面样板
  • 开展网站建设服务wordpress导航菜单均报404
  • 电视网站免费大全网站建设维护百家号
  • 人工智能与虚拟现实技术
  • Atlas 200I AI加速模块-修改和打包文件系统
  • Linux中ping时网络不可达
  • 公司做网站 微信平台急招程序员
  • 广安住房和城乡建设厅网站企业文化墙设计图效果图
  • 2025年9月电子学会全国青少年软件编程等级考试(Python二级)真题及答案
  • 20.管理存储堆栈
  • 深圳网站建设黄浦网络-技术差专业3合1网站建设