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

深圳网站设计灵点网络品牌网上做广告怎么收费

深圳网站设计灵点网络品牌,网上做广告怎么收费,苹果风格网站,wordpress模拟装机运算符承载,是编程更灵活 文章目录 运算符承载,是编程更灵活1.复数类comlex2.string类3.迭代器iterator4.vector容器 迭代器实现5.容器的迭代器失效问题6.深入理解new和delete原理7.new和delete重载实现对象池应用 1.复数类comlex 定义复数类, 实现的重载函数 # 复数类 */ cl…

运算符承载,是编程更灵活

文章目录

  • 运算符承载,是编程更灵活
    • 1.复数类comlex
    • 2.string类
    • 3.迭代器iterator
    • 4.vector容器 迭代器实现
    • 5.容器的迭代器失效问题
    • 6.深入理解new和delete原理
    • 7.new和delete重载实现对象池应用

1.复数类comlex

  1. 定义复数类, 实现+的重载函数

    # 复数类
    */  
    class CComplex  
    {  
    public:  //这个构造函数可以有三种情形// (int, int) (int) ()CComplex(int r = 0, int i = 0)  :mreal(r), minage(i) {}  // 复数类与复数类相加CComplex operator+(const CComplex &src){//CComplex comp;//comp.mreal= this->mreal+src.mreal;//comp.minage= this->minage+src.minage;//return comp;return CComplex(this->mreal+src.mreal,this->minage+src.minage );}//后置++CComplex operator++(int){//CComplex comp;//comp.mreal= this->mreal+src.mreal;//comp.minage= this->minage+src.minage;//return comp;return CComplex(this->mreal++,this->minage++ );}//前置++CComplex& operator++(){//CComplex comp= *this;mreal+=1;minage+=1;//return comp;return *this;}//+=    CComplex& operator+=(const CComplex &src)
    {this->mreal += src.mreal;this->minage += src.minage;return *this;
    }void show(){...}
    private:  int mreal;  int minage;  friend CComplex operator+(const CComplex &lhs, const CComplex &src);// 友元函数声明friend std::ostream& operator<<(std::ostream &os, const CComplex &src);
    };  
    //但是需要友元, 类外访问私有, 这个不是类成员方法, 所以不需要作用域
    CComplex operator+(const CComplex &lhs, const CComplex &src){//CComplex comp;//comp.mreal= this->mreal+src.mreal;//comp.minage= this->minage+src.minage;//return comp;return CComplex(lhs.mreal+src.mreal,lhs.minage+src.minage );}// 全局 operator<< 重载  注意, 流不能用const修饰
    std::ostream& operator<<(std::ostream &os, const CComplex &src)
    {os << "Real: " << src.mreal << ", Imaginary: " << src.minage;return os;
    }int main()  
    {  CComplex comp1(10, 10);  CComplex comp2(20, 20); //需要+重载CComplex comp3 = comp1 + comp2;  //与整型相加CComplex comp4 = comp1 + 40;  /*40是int, 一般是要找对应的+重载: operator(int)->但是, 编译器会先int转化为复数类, 找有没有 CComplex(int) 的构造函数, 而正好, 构造函数的三种情形有这个->因此不用写重载了, 编译器会使用构造函数把这个转化为复数类*/// 编译器做对象运算时, 优先调用对象的成员方法, 如果没有, 会在全局作用域找合适的//下面这个整型加, 需要在 全局作用域有重载函数CComplex comp5 = 30 + comp2;//这是不行的, int在前, 上一个可以 是因为编译器调用了 左边comp1的+, 这个则没有//operator++() 后置++       operator++(int) 后置++comp5 = comp1++;comp5 = ++comp1;//+=重载comp5 += comp1;//cout<< 重载   ostream// cin>>重载    istreamreturn 0;  
    }
    

2.string类

string更灵活简便, 有+重载,> == < 重载, const char*可没有, 需要调函数

仅供参考!

#include <iostream>
#include <cstring>class String
{
public:// 构造函数String(const char *p = nullptr){if (p != nullptr){_pstr = new char[strlen(p) + 1];strcpy(_pstr, p);}else{_pstr = new char[1];*_pstr = '\0';}}// 析构函数~String(){delete[] _pstr;_pstr = nullptr;}// 拷贝构造函数String(const String &other){_pstr = new char[strlen(other._pstr) + 1];strcpy(_pstr, other._pstr);}// 赋值运算符重载String &operator=(const String &other){if (this != &other) // 防止自赋值{delete[] _pstr;_pstr = new char[strlen(other._pstr) + 1];strcpy(_pstr, other._pstr);}return *this;}// 加法运算符重载--未优化, 多了一次new,deleteString operator+(const String &other) const{char *newtmp = new char[strlen(_pstr) + strlen(other._pstr) + 1];strcpy(newtmp, _pstr);strcat(newtmp, other._pstr);String newString(newtmp);delete[]newtmp;return newString;}// 加法运算符重载--小优化后String operator+(const String &other) const{String newString;newString._pstr = new char[strlen(_pstr) + strlen(other._pstr) + 1];strcpy(newString._pstr, _pstr);strcat(newString._pstr, other._pstr);return newString;}// 比较运算符重载bool operator>(const String &other) const{return strcmp(_pstr, other._pstr) > 0;}bool operator<(const String &other) const{return strcmp(_pstr, other._pstr) < 0;}bool operator==(const String &other) const{return strcmp(_pstr, other._pstr) == 0;}// 长度方法size_t length() const{return strlen(_pstr);}// 下标运算符重载char &operator[](size_t index){return _pstr[index];}const char &operator[](size_t index) const{return _pstr[index];}// 输出运算符重载friend std::ostream &operator<<(std::ostream &os, const String &str){os << str._pstr;return os; }// 输入运算符重载friend std::istream &operator>>(std::istream &is, String &str){char buffer[1024];is >> buffer;str = String(buffer);return is;  // 支持链式操作  例如: cin>>a>>b,第一次cin>>a返回cin, 即后面的变为 cin>>b}private:char *_pstr;
};int main()
{String str1 = "Hello";String str2 = "World";String str3 = str1 + " " + str2;std::cout << str3 << std::endl; // 输出: Hello Worldif (str1 > str2)std::cout << "str1 is greater than str2" << std::endl;else if (str1 < str2)std::cout << "str1 is less than str2" << std::endl;elsestd::cout << "str1 is equal to str2" << std::endl;std::cout << "Length of str1: " << str1.length() << std::endl;return 0;
}

3.迭代器iterator

继续优化 operator+

  1. 对于原始的stl的string类, 使用迭代器, 一个个 输出

    String str1 = "hello hzh";
    string::iterator it = str1.begin(); //或者auto
    auto it = str1.begin(); 
    for(; it!=str1.end();++it)
    {cout << *it <<" "; 
    }
    
  2. 迭代器可以透明的访问 容器内部的 元素的值, 不需要考虑 类型

  3. 泛型算法–全局的函数—给所有容器用的

  4. 泛型算法, 有一套方式, 能够统一的遍历所有容器的元素–迭代器

  5. 写一个自定义的 迭代器, 嵌套在上一个自定义的String类

    // 自定义迭代器class iterator{public:iterator(char *ptr = nullptr) : _ptr(ptr) {}// 解引用操作符char &operator*() const{return *_ptr;}// 前置递增操作符iterator &operator++(){++_ptr;return *this;}// 后置递增操作符iterator operator++(int){iterator tmp = *this;++_ptr;return tmp;}// 相等操作符bool operator==(const iterator &other) const{return _ptr == other._ptr;}// 不相等操作符bool operator!=(const iterator &other) const{return _ptr != other._ptr;}private:char *_ptr;};// 返回指向字符串开头的迭代器iterator begin(){return iterator(_pstr); //这样写不能引用哈, 因为是局部变量}// 返回指向字符串结尾的迭代器iterator end(){return iterator(_pstr + length());  }private:char *_pstr;
    };
  6. c++11里,有方便的 迭代器调用方式:

    for(char ch : str1)
    {cout << ch <<" "; 
    }
    
  7. 迭代器功能:
    提供一种统一的方式, 来透明遍历容器

4.vector容器 迭代器实现

    // 自定义迭代器class iterator{public:iterator(T* ptr = nullptr) : _ptr(ptr) {}// 解引用操作符T& operator*() const{return *_ptr;}// 前置递增操作符iterator& operator++(){++_ptr;return *this;}// 后置递增操作符iterator operator++(int){iterator tmp = *this;++_ptr;return tmp;}// 相等操作符bool operator==(const iterator& other) const{return _ptr == other._ptr;}// 不相等操作符bool operator!=(const iterator& other) const{return _ptr != other._ptr;}private:T* _ptr; // 指向当前元素的指针};// 返回指向容器开头的迭代器iterator begin(){return iterator(_first);}// 返回指向容器末尾的迭代器iterator end(){return iterator(_last);}

对于vector, 是可以用下标的

5.容器的迭代器失效问题

新学两个 容器 的函数, 添加和删除
容器对象.insert(it, val) 容器对象.erase(it) --这两都是 要传入迭代器!!

  1. 迭代器失效-1

    //删除所有的偶数
    for(; it!=vec.end(); ++it)
    {if(*it %2 ==0){// 第一次调用erase后, it就失效了, 不能再++了,vec.erase(it);}}
    
  2. 迭代器失效-2

    //在所有偶数前面添加一个小于偶数值1的值
    for(; it!=vec.end(); ++it)
    {if(*it %2 ==0){// 第一次调用insert后, it就失效了vec.insert(it, *it-1);}}
    
  3. 迭代器为什么会失效?

    1. 删除(erase)或增加(insert)it的地方后, 当前位置及后续的迭代器全部失效, 但是之前的仍然有效
    2. insert如果引起容器扩容, 会整体全部失效, 不是一块内存了
    3. 不同容器迭代器不能进行比较
  4. stl的容器, 删除后解决办法, for里不要++, 并更新 迭代器, 当前位置it

    //删除所有的偶数
    for(; it!=vec.end();)
    {if(*it %2 ==0){// 第一次调用erase后, it就失效了, 不能再++了,it = vec.erase(it);}else{++it;}}
    
  5. stl的容器,增加但不扩容, 解决办法, 要+两次

    //在所有偶数前面添加一个小于偶数值1的值
    for(; it!=vec.end(); ++it)
    {if(*it %2 ==0){// 第一次调用insert后, it就失效了vec.insert(it, *it-1);++it;}
    }
    
  6. 迭代器失效原理?
    vector 解决失效的 代码 -整体使用链表来存储迭代器,-- 这也就导致了 链表节点处对不上, 将会失效

  7. 了解 原理, 知道什么时候会失效, 其余的代码, 讲的有点乱–网上看看

6.深入理解new和delete原理

  1. new和delete 本质是 运算符重载
    从汇编看, 会调用 operator new 和 operator delete

  2. 回顾1.8节, new, delete, malloc, free 区别
    malloc按字节开辟内存;new开辟需要指定类型 new int[10]
    so, malloc 开辟内存返回的都是 void*, operator new-> int*
    malloc只负责开辟, new不仅开辟, 还初始化
    malloc 错误返回 nullptr, new抛出bad_alloc类型异常

    delete: 调用析构, 再free, free: 仅释放内存

  3. new实现–简化版

    //先开辟内存, 再调用对象构造函数
    void* operator new(size_t size)
    {void *p = malloc(size);if(p == nullptr)throw bad_alloc();return p;
    }
    //调用 对象的 析构, 再释放
    void operator delete(void* p) noexcept
    {if (p != nullptr) {free(p);  // 释放由 malloc 分配的内存}
    }
    //delete 操作符通常被标记为 noexcept,表示它不会抛出异常。这是为了确保在析构对象时不会因为内存释放失败而抛出异常。// 自定义 new[] 操作符
    void* operator new[](size_t size)
    {void* p = std::malloc(size);  // 使用 malloc 分配内存if (p == nullptr) {throw std::bad_alloc();  // 如果分配失败,抛出 bad_alloc 异常}return p;
    }// 自定义 delete[] 操作符
    void operator delete[](void* p) noexcept
    {std::free(p);  // 使用 free 释放内存
    }int main()
    {try{int *p=new int;delete p;}catch(const bad_alloc &err){cerr << err.what() << endl;}
    }
    
  4. new和delete能混用吗? cpp为什么要区分 单个元素释放和 数组释放?—面试重点
    new/delete
    new[]/delete[]
    对于普通的 编译器内置类型(int等), 可以混用, new/delete[] new[]/delete
    对于自定义类 类型, 有析构, 为了调用正确的析构, 开辟对象数组的时候, 会多开辟4个字节, 记录对象的个数, 混用会导致 无法正确释放 这多出来的 4字节

  5. 为什么自定义类, 需要额外开辟?
    因为普通类型的大小是固定的,编译器可以直接计算。delete 不需要额外信息来释放内存,

  6. 自己补充的剖析: 那么为什么,普通类型不需要?
    本质是析构的问题, new/delete 不会主动计算有几个对象的
    对于一般类型, new[]开辟一个完整的内存块, 由于没有析构, 不需要遍历, 所以直接释放即可
    而有析构的类, 在delete时, 需要一个个遍历 析构函数, 而编译器不知道数组里有几个对象, 需要遍历几次, 因此必须开辟一个额外的空间,存储有几个 对象

7.new和delete重载实现对象池应用

对象池: 对象复用
对象池是一种通过预先创建并重复使用对象来减少创建和销毁开销,从而提升性能的设计模式。

  1. 对于这个程序, 会大量调用 new和delete, 影响性能
template<typename T>
class Queue
{
public:Queue(){_front = _rear = new QueueItem();}//析构需要遍历~Queue(){while (_front != nullptr){QueueItem* temp = _front;_front = _front->_next;delete temp;}}// 添加入队元素void push(const T& data){QueueItem* newItem = new QueueItem(data);_rear->_next = newItem;_rear = newItem;}// 出队操作bool pop(T& data){if (_front == _rear){return false; // 队列为空}QueueItem* temp = _front->_next;data = temp->_data;_front->_next = temp->_next;if (_rear == temp){_rear = _front; // 如果出队的是最后一个元素,重置 _rear}delete temp;return true;}private:struct QueueItem{QueueItem(T data = T()) : _data(data), _next(nullptr) {}T _data;QueueItem* _next;};QueueItem* _front; // 指向头节点QueueItem* _rear;  // 指向队尾
};int main()
{Queue<int> q;q.push(10); //大量调用 new和delete, 每次新元素都要newq.push(20);q.push(30);int data;while (q.pop(data)){std::cout << "Dequeued: " << data << std::endl;}return 0;
}

解决办法: 使用对象池, new和delete重载, 使得push不需要开辟新的

#include <iostream>
using namespace std;#define POOL_ITEM_SIZE 100000template<typename T>
class Queue
{
private:struct QueueItem{T _data;QueueItem* _next;static QueueItem* _itemPool;QueueItem(T data = T()) : _data(data), _next(nullptr) {} //零构造// 重载 operator new,使用对象池管理内存void* operator new(size_t size){if (_itemPool == nullptr){// 预分配 POOL_ITEM_SIZE 个 QueueItem_itemPool = reinterpret_cast<QueueItem*>(new char[POOL_ITEM_SIZE * sizeof(QueueItem)]);QueueItem* p = _itemPool;for (0; p < _itemPool + POOL_ITEM_SIZE - 1; ++p){p->_next = p + 1; // 链接对象池中的空闲对象}p->_next = nullptr; // 结束链表}// 从对象池取出一个对象QueueItem* p = _itemPool;_itemPool = _itemPool->_next;//p->_next = nullptr; // 防止误用return p;}// 重载 operator delete,将对象归还到池中void operator delete(void* ptr){QueueItem* obj = static_cast<QueueItem*>(ptr);obj->_next = _itemPool;_itemPool = obj;}};QueueItem* _front; // 头指针(哨兵)QueueItem* _rear;  // 尾指针public:Queue(){_front = new QueueItem(); // 创建哨兵节点_rear = _front;           // 初始时 rear 指向 frontcout << "Queue" << endl;}~Queue(){while (_front != nullptr){QueueItem* temp = _front;_front = _front->_next;delete temp; // 归还到对象池}cout << "~Queue" << endl;}// 入队操作void push(const T& data){QueueItem* newItem = new QueueItem(data); // 从对象池获取, new重载了_rear->_next = newItem;_rear = newItem;}// 出队操作bool pop(T& data){if (_front->_next == nullptr){return false; // 队列为空}QueueItem* temp = _front->_next;data = temp->_data;_front->_next = temp->_next;if (_rear == temp){_rear = _front; // 如果出队的是最后一个元素,重置 _rear}delete temp; // 归还到对象池return true;}
};// 初始化静态成员变量
template<typename T>
typename Queue<T>::QueueItem* Queue<T>::QueueItem::_itemPool = nullptr;int main()
{Queue<int> q;q.push(10);q.push(20);q.push(30);int value;while (q.pop(value)){std::cout << "Popped: " << value << std::endl;}return 0;
}
http://www.dtcms.com/wzjs/35106.html

相关文章:

  • 带搜索网站建设视频教程seo如何优化的
  • 金万邦网站备案信息真实性核验单百度一下生活更好
  • 网站建设与管理心得成都网站seo公司
  • 国外做设备网站产品怎么做市场推广
  • 什么是互联网企业东莞seo网络公司
  • 衡阳电商网站建设定制网站开发公司
  • 查企业不要钱的软件seo chinaz
  • 东莞网站建设-拥有多年专业中国最新领导班子
  • 自己做网站还是挂靠好腾讯疫情实时数据
  • 绍兴建设公司网站网站建设推广多少钱
  • 网站banner的作用今日国际重大新闻
  • php做电商网站百度关键词推广怎么收费
  • 大型网站开发协调新闻发稿
  • 电子商务网站名称广东病毒感染最新消息
  • 空白的网站怎么建设网络事件营销案例
  • 做别人一摸一样的网站犯法吗百度云盘资源共享链接群组链接
  • 网站建设实训总结新闻网最新消息
  • app 微商城网站建设软文营销网
  • 制作网线的线序百度seo和sem的区别
  • asp.net动态网站开发崔宁广告牌
  • 哪个平台买东西最便宜seo排名方案
  • 牡丹江做网站建设下载百度到桌面上
  • 百度验证网站的好处百度地图疫情实时动态
  • php网站超市源码下载seo推广的常见目的有
  • 做游戏任务赚钱的网站有哪些seo课
  • 镇江网站制作哪家公司比较好百度号码认证平台官网首页
  • 华为云建网站外链群发
  • 网站建设威客平台地推十大推广app平台
  • 《网站开发与应用》大作业要求网页设计成品源代码
  • 网站建设联系方式高级搜索百度