string类模拟实现
了解过string常用接口后,接下来的任务就是模拟实现string类。
目录
VS下的string结构
默认成员函数和简单接口
string结构
c_str()、size()、capacity()、clear()、swap()
构造函数
拷贝构造函数
赋值重载
析构函数
访问及遍历
容量操作
reserve
resize
修改操作
push_back
append
operator+=
insert
earse
输入/输出运算符重载
VS下的string结构
■首先测试下string结构的大小(注:下述测试是在32位平台上进行的,指针占4个字节)
int main()
{string s;cout << sizeof(s) << endl;return 0;
}
通过调试窗口理解string的结构:
int main()
{string s("Hello");return 0;
}
通过测试知道string总共占28个字节,调试发现结构中有一个联合体,用来定义string中字符串的存储空间: 1.当字符串长度小于16时,使用内部固定的字符数组来存放 。2.当字符串长度大于等于16时,从堆上开辟空间。
union _Bxty
{ char _Buf[16];char* _Ptr;char _Alias[16];
} _Bx;
除了联合体,还有一个size_t字段保存字符串长度,还有一个size_t字段记录容量!此外,还有一个做其它事情的指针。总大小:16+4+4+4 = 28 !!
默认成员函数和简单接口
下述接口的模拟实现仅仅是一种写法,可能不是最优的,也可能存在一些BUG,仅供参考!
string结构
c_str()、size()、capacity()、clear()、swap()
为了测试方便,先将上述几个常用且简单的接口进行实现:
//返回指向_str的指针const char* c_str(){return _str;}//返回_sizesize_t size() const{return _size;}//返回_capacitysize_t capacity() const{return _capacity;}//清空有效字符void clear(){_size = 0;_str[0] = '\0';}
复习时间:const修饰返回值的作用是避免返回值被修改,const写在成员函数后面修饰的是隐藏的this指针,不能对类的成员进行修改!
swap:string类中提供一个swap接口用来交换两个string对象。
void swap(string& s){std::swap(_str, s._str);std::swap(_size,s._size);std::swap(_capacity, s._capacity);}
构造函数
分析:对于string s1(“Hello”)/ string s2 都能处理;
逻辑思路:通过strlen计算str的字符个数,确定size和capacity的值,空间一般多开一个,因为要算上\0。在将str 拷贝到开辟好的空间中。
//构造 string(const char* str = "") {_size = strlen(str);_capacity = _size;_str = new char[_capacity+1];strcpy(_str,str);cout << "调用构造函数!" << endl; }
测试代码:
//构造函数测试void TestString1(){string s1("zhang");string s2;cout << s1.c_str() << endl;}
拷贝构造函数
分析:string s1(s2);
按照拷贝对象的容量申请空间,对拷贝对象进行拷贝。
传统写法:
//拷贝构造string(const string& s){_str = new char[s._capacity];_size = s._size;_capacity = s._capacity;strcpy(_str,s._str);cout << "调用拷贝构造!" << endl;}
测试代码:
//拷贝构造测试void TestString2(){string s2("Hi zxy!");cout << s2.c_str() << endl;string s3(s2);cout << s3.c_str() << endl;}
现代写法:这里注意在初始化列表对s进行初始化,否则当tmp对象析构的时候,会出现析构野指针的问题。
//现代写法string(const string& s):_str(nullptr),_size(0),_capacity(0){string tmp(s._str);//this->swap(tmp);swap(tmp);cout << "拷贝构造" << endl;}
赋值重载
传统写法:
注意:不要见到&就是引用,在下述判断代码中,&s取出的s的地址,和this指针进行比较,如果地址不相同则进行赋值工作!
赋值的过程需要将右操作数赋值给做左操作数,这时从新根据右操作数的容量申请一块空间,将左操作数空间释放。_str指向刚刚开好的空间,将右操作数中的字符串拷贝到_str中。
//赋值重载string& operator=(const string& s){//两操作数地址不相等if (this != &s){//申请一块能容纳右操作数的空间char* tmp = new char[s._capacity];delete[] _str;_str = tmp;strcpy(_str,s._str);_size = s._size;_capacity = s._capacity;}return *this;}
测试代码:
//赋值重载测试void TestString3(){string str1("Hello World!");string str2("Hi!");cout <<"赋值前str1:"<< str1.c_str() << " str2:" << str2.c_str() << endl;str1 = str2;cout <<"赋值后str1:"<< str1.c_str() << " " << str2.c_str() << endl;}
测试结果:
现代写法:
第二种相比较第一种写法省去了一次拷贝构造,传值调用形参是实参的临时拷贝,所以第二种写法更加的简洁,第一种写法更容易理解。
//赋值重载现代写法1string& operator=(string& s){if (this != &s){//string tmp(s._str);string tmp(s);swap(tmp);}return *this;}
//赋值重载现代写法2string& operator=(string s){swap(s);return *this;}
析构函数
//析构~string(){_capacity = _size = 0;delete[] _str;_str = nullptr;cout << "调用析构函数!" << endl;}
测试代码:
//析构函数测试void TestString4(){string str("zxy");cout << str.c_str() << endl;}
访问及遍历
operator[ ]
char& operator[](size_t pos){assert(pos < _size);return _str[pos];}char& operator[](size_t pos) const{assert(pos < _size);return _str[pos];}
begin/end
typedef char* iterator;iterator begin(){return _str;}iterator end(){return _str + _size;}
迭代器:访问string对象、vector等对象元素的一种通用机制。迭代器类似于指针类型(不一定是指针),使用迭代器可以访问某个元素。范围for的支持就和迭代器有关:
void TestString2(){string s2("My name is zxy!");string::iterator it1 = s2.begin();while (it1 != s2.end()){cout << *it1;it1++;}cout << endl;string::iterator it2 = s2.begin();while (it2 != s2.end()){(*it2)++;cout << *it2;it2++;}}
证明范围for是依赖于迭代器实现的:
1.屏蔽掉string中的begin或者end.
2.放开屏蔽,更改begin的命名为Begin。一样的报错
3.提供小写的begin和end
综上所述:便捷神秘的范围for,运用迭代器这种通用的机制来实现元素的遍历和访问。
容量操作
reserve
扩容:申请一块n大小的空间,将_str指向的字符串拷贝到tmp指向的空间中,清理_str指向的字符串并将_str指向新空间,更新容量的大小。
//扩容void reserve(size_t n){//新开一块空间char* tmp = new char[n + 1];strcpy(tmp, _str);delete[] _str;_str = tmp;_capacity = n;}
void TestString6(){string ss("Hello World!");cout << "size:" << ss.size() << endl;cout << "capacity:" << ss.capacity() << endl;cout << "str:" << ss.c_str() << endl;cout << "--------------reserve--------------" << endl;ss.reserve(100);cout << "size:" << ss.size() << endl;cout << "capacity:" << ss.capacity() << endl;cout << "str:" << ss.c_str() << endl;}
resize
改变字符串中有效字符的个数,当n>_size时,其余位置用ch占位。当n<_size时只有前n个字符是有效字符。
//resize,更改有效元素个数的大小void resize(size_t n,char ch = '!'){if (n > _size){reserve(n);for (size_t i = _size;i < n; i++){_str[i] = ch;}_size = n;_str[n] = '\0';}else{_size = n;_str[n] = '\0';}}
上述代码中,当n小于_size时,在n位置填入\0,有效字符的个数正好是n,因为字符数组的下标是从0开始的。
void TestString7(){string ss("Hello");cout << "str:" << ss.c_str() << endl;cout << "size:" << ss.size() << endl;//字符串有效字符个数增多ss.resize(10,'x');cout << "str:" << ss.c_str() << endl; cout << "size:" << ss.size() << endl;//字符串有效字符个数变少ss.resize(3);cout << "str:" << ss.c_str() << endl;cout << "size:" << ss.size() << endl;}
修改操作
push_back
尾插操作,也就是在字符串末尾追加一个字符:
//追加字符void push_back(char ch){if (_size == _capacity){size_t newcapacity = _capacity == 0 ? 4 : 2 * _capacity;//扩容reserve(newcapacity);}_str[_size++] = ch;_str[_size] = '\0';}
append
在_str末尾追加一个字符串:
//追加字符串void append(const char* str){size_t len = strlen(str);if (_size + len > _capacity){reserve(_size+len+1);}strcpy(_str+_size,str);_size += len;}
operator+=
重载+=运算符,使+=既可以追加字符右可以追加字符串,实现思路和上述基本一样,这里直接调用上面的接口。
//运算符重载string& operator+=(char ch){push_back(ch);return *this;}string& operator+=(const char* str){append(str);return *this;}
测试push_back/append/+=性能
void TestString3(){string ss("Hi");cout << "str:" <<ss.c_str() << endl;ss.append("zxy"); cout << "append(zxy):" <<ss.c_str() << endl;ss.push_back('!');cout << "push_back(!):" <<ss.c_str()<< endl;ss += '!';cout << "+=字符(!):" <<ss.c_str() << endl;ss += "bd";cout << "+=字符串(bd):" <<ss.c_str() << endl;}
insert
insert这里重载了两个接口,分别是用来插入字符和插入字符串:
●在pos位置插入字符
![]()
//插入字符string& insert(size_t pos,char ch){//检查pos是否越界assert(pos <= _size);if (_capacity == _size){//扩容size_t newcapacity = _capacity == 0 ? 4 : 2 * _capacity;reserve(newcapacity);}//挪动数据size_t end = _size + 1;while (end > pos){_str[end] = _str[end-1];end--;}_str[pos] = ch;_size++;return *this;}
void TestString9(){string ss("Helloworld!");ss.insert(6, ' ');cout << ss.c_str() << endl;}
●在pos位置插入字符串:
//插入字符串 string& insert(size_t pos, const char* str){assert(pos <= _size);size_t len = strlen(str);if (_size + len > _size){//扩容size_t newcapacity = _capacity == 0 ? 4 : _size+len;reserve(newcapacity);}//挪动数据size_t end = _size + len;while (end > pos+len-1){_str[end] = _str[end - len];end--;}strncpy(_str+pos,str,len);_size += len;return *this;}
void TestString10(){string ss("Hi Lisi!");ss.insert(3, "zxy I am ");cout << ss.c_str() << endl;}
earse
删除pos后的len个字符,如果len == npos,将pos后的数据全部删除!
//删除字符string& earse(size_t pos,size_t len = npos){assert(pos <= _size);//如果pos后面的数据不够删或者=npos,pos后数据全部删除if (len == npos || len + pos >= _size-pos){_str[pos] = '\0';_size = pos;}else{strcpy(_str + pos, _str + pos + len);_size -= len;}return *this;}
输入/输出运算符重载
小提问:输入和输出的重载为了和我们的使用习惯保持一致一般会定义在全局,那么一定要在对应自定义类型中声明友元吗?
答:不一定,声明友元的原因是要访问类中的私有成员,如果在重载的过程中不涉及私有成员的访问,就不用写友元声明!
//流插入ostream& operator<<(ostream& out,string& s){for (size_t i = 0; i < s.size(); i++){out << s[i];}return out;}
流提取的实现使用了一个字符数组,in.get()用于读取字符,当数组满时追加到_str中,没满时将数据存放到buff数组中,最后输入结束时如果buff中还有数据的话将剩余数据追加到_str中,不过要注意在buff的数据末尾添加一个\0。
//流提取istream& operator>>(istream& in, string& s){s.clear();char ch = in.get();size_t i = 0;char buff[128] = {'\0'};while (ch != ' ' && ch != '\n'){if (i == 127){s += buff;i = 0;}buff[i++] = ch;ch = in.get();}if (i > 0){buff[i] = '\0';s += buff;}return in;}
相关文章:
![](https://img-blog.csdnimg.cn/2fa801d0ed1e410284ea59ca72630c9e.png)
string类模拟实现
了解过string常用接口后,接下来的任务就是模拟实现string类。 目录 VS下的string结构 默认成员函数和简单接口 string结构 c_str()、size()、capacity()、clear()、swap() 构造函数 拷贝构造函数 赋值重载 析构函数 访问及遍历 容量操作 reserve resize …...
![](https://img-blog.csdnimg.cn/5d08cae03896451689d88a706917581a.png)
cadence SPB17.4 S032 - allegro - 保存/载入光绘层定义
文章目录cadence SPB17.4 S032 - allegro - 保存/载入光绘层定义概述保存光绘层在新板子中载入已经保存的相同类型老板子定义好的光绘层定义文件碎碎念ENDcadence SPB17.4 S032 - allegro - 保存/载入光绘层定义 概述 以前布线完成, 准备出板厂文件时, 总是要手工重新建立光绘…...
![](https://img-blog.csdnimg.cn/img_convert/1cb67a78c449c3a44b493f352afe17b8.png)
微服务实战--高级篇:分布式缓存 Redis
分布式缓存 – 基于Redis集群解决单机Redis存在的问题 单机的Redis存在四大问题: 1.Redis持久化 Redis有两种持久化方案: RDB持久化AOF持久化 1.1.RDB持久化 RDB全称Redis Database Backup file(Redis数据备份文件)…...
![](https://www.ngui.cc/images/no-images.jpg)
【C语言】可变参数列表
本篇博客让我们来认识一下C语言学习过程中往往被忽略的可变参数列表 所谓可变参数,就是一个不限定参数数量的函数,我们可以往里面传入任意个数的参数,以达成某些目的。 关联:C11可变模板参数;本文首发于 慕雪的寒舍 …...
![](https://img-blog.csdnimg.cn/bc98f90bfd694e8eb65251fbb050a7a0.png)
目标检测的旋框框文献学习
这是最近打算看完的文献,一天一篇 接下来将记录一下文献阅读笔记,避免过两天就忘了 RRPN 论文题目:Arbitrary-Oriented Scene Text Detection via Rotation Proposals 论文题目:通过旋转方案进行任意方向的场景文本检测&#x…...
![](https://www.ngui.cc/images/no-images.jpg)
Hive 在工作中的调优总结
总结了一下在以往工作中,对于Hive SQL调优的一些实际应用,是日常积累的一些优化技巧,如有出入,欢迎在评论区留言探讨~ EXPLAIN 查看执行计划 建表优化 分区 分区表基本操作,partitioned二级分区动态分区 分桶 分…...
![](https://maynor-demo.oss-cn-shenzhen.aliyuncs.com/img/20230210165222.png)
每天一道大厂SQL题【Day09】充值日志SQL实战
每天一道大厂SQL题【Day09】充值日志SQL实战 大家好,我是Maynor。相信大家和我一样,都有一个大厂梦,作为一名资深大数据选手,深知SQL重要性,接下来我准备用100天时间,基于大数据岗面试中的经典SQL题&#…...
![](https://img-blog.csdnimg.cn/22cebc7421754b4fa9ca2aecd4eb1d04.gif#pic_center)
MATLAB 遗传算法
✅作者简介:人工智能专业本科在读,喜欢计算机与编程,写博客记录自己的学习历程。 🍎个人主页:小嗷犬的个人主页 🍊个人网站:小嗷犬的技术小站 🥭个人信条:为天地立心&…...
![](https://www.ngui.cc/images/no-images.jpg)
探讨 Java 中 valueOf 和 parseInt 的区别
前言 在编程中,遇到类型转换,好像会经常用到 parseInt 和 valueOf,当然这里只拿 Integer 类型进行陈述,其他类型也是雷同的; 想必有读者也跟我一样,经常交叉使用这两个方法,但却不知道这两者到…...
![](https://img-blog.csdnimg.cn/img_convert/11b4ba84b9764bcb8e2972118d072bce.png)
JSON学习笔记
♥课程链接:【狂神说Java】一小时掌握JSON_哔哩哔哩_bilibili配套的当然还要学习ajax不管是前端后端,感觉这部分内容是必须的,不然真的做项目的时候云里雾里。总体json的内容不多,具体就:1. 列表、对象等语法格式2. js…...
![](https://img-blog.csdnimg.cn/c862b4849ff64bb5bc1db1a3e0ce9417.png)
家政服务小程序实战教程07-轮播图组件
小程序中首页一般显示轮播图的功能,点击轮播图会跳转到具体的一篇文章或者是产品,本篇我们就介绍一下轮播图功能的开发 01 设计数据源 我们轮播图组件需要两个字段,一个是展示的图片,一个是跳转页面传入的参数。打开数据源&…...
![](https://www.ngui.cc/images/no-images.jpg)
MySQL之索引创建、删除、唯一索引、普通索引、及命名规则、注意事项
一、MySQL 索引 定义 索引是一个数据结构,用于加速数据库表中数据的查询。索引存储了一些数据表中的列值,以及这些列值在数据表中的位置,这样就可以通过索引来快速查找到数据表中的某一行数据。 MySQL 支持多种索引类型,包括普通…...
![](https://img-blog.csdnimg.cn/87dbd03958ad4675aab704226ff1ceee.png)
【C++设计模式】学习笔记(3):策略模式 Strategy
目录 简介动机(Motivation)模式定义结构(Structure)要点总结笔记结语简介 Hello! 非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出~ ଘ(੭ˊᵕˋ)੭ 昵称:海轰 标签:程序猿|C++选手|学生 简介:因C语言结识编程,随后转入计算机专业,获得过国家奖学金…...
![](https://img-blog.csdnimg.cn/6fc0f340e4bd4d6aa3065908badd1ce7.png)
Java——聊聊JUC中的ThreadLocal
文章目录: 1.什么是ThreadLocal? 1.1 api介绍 1.2 最简单的案例认识ThreadLocal 1.3 线程池结合ThreadLocal案例 2.Thread &ThreadLocal & ThreadLocalMap 3.ThreadLocal内存泄漏问题 3.1 四大引用之强引用 3.2 四大引用之软引用 3.3 四…...
![](https://img-blog.csdnimg.cn/284c30f7a5c94d0a85210a17215506ea.jpeg)
软件工程(4)--螺旋模型
前言 这是基于我所学习的软件工程课程总结的第四篇文章。 在软件开发过程中必须及时识别和分析风险,并且采取适当措施以消除或减少风险的危害。构建原型是一种能使某些类型的风险降至最低的方法。为了降低交付给用户的产品不能满足用户需要的风险,一种行…...
![](https://img-blog.csdnimg.cn/img_convert/0f264d2446bbb5f6eed30945dbf94d39.png)
图解LeetCode——剑指 Offer 50. 第一个只出现一次的字符
一、题目 在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。 二、示例 2.1> 示例 1: 【输入】s "abaccdeff" 【输出】b 2.2> 示例 2: 【输入】s "" 【输出】 限制: 0 < s 的…...
![](https://www.ngui.cc/images/no-images.jpg)
《HTML 5与CSS 3核心技法》读书笔记
目录前言第1章 写在前面第2章 HTML 语法基础第3章 布局类元素 ,房子的楼板、柱子和大梁第4章 功能类元素,房子的门、窗、水管和电气第5章 CSS基础第6章 选择器,确定样式的作用范围选择器类型选择器的组合使用第7章 权重,样式发送冲…...
![](https://img-blog.csdnimg.cn/img_convert/e097a33616c6ff2fd8e4c7a3569c1ffe.png)
【沐风老师】3DMAX几何投影插件Geometry Projection使用详解
【几何投影插件】 描述 3DMAX几何投影插件Geometry Projection,将一个或多个对象或它的顶点选择沿全局或局部 x、y 或 z 轴投影到另一个对象上。 适用版本 3dMax2013或更高版本 安装设置 插件的安装非常简单,解压后把插件脚本 “geometry_projectio…...
![](https://www.ngui.cc/images/no-images.jpg)
面试问题整理
20200422面试题 1、有nginx为什么还要用gateway 2、factorybean和beanfactory有什么区别 https://www.cnblogs.com/leeego-123/p/12159574.html 2、aop原理 3、ioc原理 4、注解requestbody和responsebody区别。pathvireable和requestparam注解区别,feign客户端的注解…...
![](https://www.ngui.cc/images/no-images.jpg)
“区块链60人”2022赋能中国区块链创新人物名单公布
2022年11月5日,“2022第五届全国高校人工智能大数据区块链教育教学创新论坛”在京隆重召开。此次论坛公布了“区块链60人”2022赋能中国区块链创新人物评选活动获评名单。 本次评选活动通过媒体报道、第三方推荐、专家评选等环节,坚持“公开、公平、公正…...
![](https://www.ngui.cc/images/no-images.jpg)
day2324 数组
文章目录相关概念codeArrayTest08 数组拷贝相关概念 day23课堂笔记 1、数组 1.1、数组的优点和缺点,并且要理解为什么。 第一:空间存储上,内存地址是连续的。 第二:每个元素占用的空间大小相同。 第三:知道首元素的内…...
![](https://img-blog.csdnimg.cn/img_convert/4a86bf119ff8ba2f9a0a6a6c30d40cf0.png)
【Python实战】神仙运气—快看看你的彩票:2千多万元大奖无人领,马上就过期了,下一期的中奖者会是你吗?(纯技术交流)
前言 越努力越幸运 哈喽~我是栗子同学! 特别注意:不管是沉迷赌球,还是沉迷购彩,都是不可取的。本文纯是一个技术学习内容。 听说关注我的人会暴富哦!、 所有文章完整的素材源码都在👇👇 粉丝…...
![](https://img-blog.csdnimg.cn/40c05fe5450a464c82cefe2c11ff4730.jpeg#pic_center)
2023年上半年软考高项信息系统项目管理师2月25日开班
信息系统项目管理师是全国计算机技术与软件专业技术资格(水平)考试(简称软考)项目之一,是由国家人力资源和社会保障部、工业和信息化部共同组织的国家级考试,既属于国家职业资格考试,又是职称资…...
![](https://img-blog.csdnimg.cn/4633da07c0834f03ac6c94f5842eaba3.png)
数据库(第一天)
文档信息 文档类别正式文档文档编号数据库基础课 1.2-001版本1.2-001文档名称数据库基础课编写负责人/编写时间梁昭东/2023 年 1 月 30 日审核负责人/审核时间年 月 日批准人/批准时间年 月 日 变更记录 日期版本号变更内容修订者2023.01.30v1.2版根据实际情况增删了部分内容…...
![](https://img-blog.csdnimg.cn/c0d7bbfb20c4442685c042978a289448.jpeg#pic_center)
一文了解 ArrayList 的扩容机制
了解 ArrayList 在 Java 中常用集合类之间的关系如下图所示: 从图中可以看出 ArrayList 是实现了 List 接口,并是一个可扩容数组(动态数组),它的内部是基于数组实现的。它的源码定义如下: public class A…...
![](https://www.ngui.cc/images/no-images.jpg)
牛态已成选股源码
{牛态已成} {条件选股} {其他类型} N:7; A1:(REF(H,N) HHV(H,((2 * N) 1))); B1:FILTER(A1,N); C1:BACKSET(B1,(N 1)); D1:FILTER(C1,N); A2:(REF(L,N) LLV(L,((2 * N) 1))); B2:FILTER(A2,N); C2:BACKSET(B2,(N 1)); D2:FILTER(C2,N); E1:((REF(LLV(L,(2 * N)),1) REF(…...
![](https://img-blog.csdnimg.cn/img_convert/9ca0b61fe518402de52525727e6e4570.png)
Python基础
Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。Python 的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具有比其他语言更有特色语法结构。小编也整理了一套关于学习Python入门…...
![](https://img-blog.csdnimg.cn/0aa6c21bd35c4921b8e0803c7b667d09.png#pic_center)
浅显易懂的说清楚小游戏与H5游戏的技术区别
从“跳一跳”到“羊了个羊”微信小游戏上线4年时间,除了涌现出不少火爆全网的小游戏之外,也有类似于“动物餐厅”、“口袋奇兵”等游戏得以在此孵化繁荣,凭借着微信强大的社交属性小游戏成为游戏厂商在桌面端、App 端、H5 端之外争夺的另一个…...
![](https://img-blog.csdnimg.cn/cce6dd02326042e08db911003d7ceae5.png)
【Python入门第七天】Python 数字
Python 数字 Python 中有三种数字类型: intfloatcomplex 为变量赋值时,将创建数值类型的变量: 实例 x 10 # int y 6.3 # float z 2j # complex如需验证 Python 中任何对象的类型,请使用 type() 函数: 实…...
![](https://www.ngui.cc/images/no-images.jpg)
Python自动化测试 软件测试最全教程(附笔记),看完可就业
最近看到很多粉丝在后台私信我,叫我做一期Python自动化测试的教程,其实关于这个问题,我也早就在着手准备了,我录制了一整套完整的Python自动化测试的教程,都上传在B站上面,大家有兴趣的可以去看一下&#x…...
![](/images/no-images.jpg)
a032网站模版/武汉武汉最新
今天在修改一个公司项目的时候出现了Abstract Error问题,在网上查找之后发现为纯虚函数引起. 但是看了代码之后,发现该类的子类的同名函数也实现了.这是什么原因呢? 后来终于找了原因. T1 Class(TObject) //这个我们假设是基类 public function f1();virtual;abstract; T…...
![](/images/no-images.jpg)
二级域名可以做网站/网络营销怎么推广
微信 php 自定义菜单我申请了一个微信公众平台的测试账号,之前已经通过验证,关注后用我的微信号向测试账号发消息可以得到测试账号的正确响应,我现在想实现微信的自定义菜单,下面用***代替了我测试账号的appid和secret,…...
![](https://s1.51cto.com/attachment/201011/222532228.jpg)
如何使网站做的更好/国家市场监督管理总局官网
鉴于个人精力有限,其他试题及答案上传、发布工作由51CTO工作人员完成,详见http://training.51cto.com/art/201010/230005.htm 转载于:https://blog.51cto.com/296525818/423007...
![](https://img-blog.csdnimg.cn/e73e99a5db354f23b5e992b05c054d9c.png)
做碳循环的网站/搜索引擎外部链接优化
文章目录0.前记1.如何封装为ModelAndView2.视图解析原理3.视图解析的过程0.前记 根据上文中的返回值解析器会根据不同的返回值解析器去解析成不同的返回值, 但是最后返回值会封装为ModelAndView。本篇的内容就是如何去封装为ModelAndView, 以及如何根据ModelAndView转为View, …...
![](https://img-blog.csdnimg.cn/44a4d48ff99c42c8af2cae5cd4766f88.png)
做网站用域名不备案怎么弄/百度seo排名如何提升
MKD编译完成后查看以下数据的大小: Code:表示程序所占用 FLASH 的大小( FLASH)。 RO-data:即 Read Only-data, 表示程序定义的常量,如 const 类型( FLASH)。 RW-data&…...
国内网站服务器/站内免费推广有哪些
开篇介绍 个人背景: 不说太多废话,但起码要让你先对我有一个基本的了解。本人毕业于浙江某二本院校,算是科班出身,毕业后就进了一家外包公司做开发,当然不是阿里的外包,具体什么公司就不透露了࿰…...