用户自定义string::reserve()
user defined string::reserve()
所以我们正在编写一堆用户定义的函数来模仿字符串类的成员函数。我被困在储备金上了。它看起来应该工作,但我错过了一些东西。我尝试了几种不同的变化,例如将this->
放在成员变量前面或将my string::
放在它们前面……我的输出不会改变,但是通过放置在函数内的cout语句,我知道它访问了函数。
代码
#include <cstdlib>
#include <iostream>
#include <string>
#include "mystring.h"
#define string mystring
using namespace std;
void check (string s, string name){
cout << "checking " << name << endl;
cout << name << " contains " << s << endl;
cout << name << " capacity() is " << s.capacity() << endl;
cout << name << " length() is " << s.length() << endl;
cout << name << " size() is " << s.size() << endl;
cout << name << " max_size() is " << s.max_size() << endl << endl;
}
int main(int argc, char** argv) {
cout<<"This is Lab 5"<<endl;
string s1("Hello, World!");//step 2
string s1name("s1");//step 3
check(s1,s1name);//step 4
check(s1,s1name);//step 5
cout << "---Testing assignment operator---nn";
{
string s2;
s2=s1;
string s2name("s2");
check(s2,s2name);
if(s1==s2)
cout<<"comparison truen";
else
cout<<"comparison falsen";
}
check(s1,s1name);
string s3("check assignment");
s3=s3;//checking to see if operator= is used when they are the same object.
check(s3,"s3");
cout<<"Lab 5 ends"<<endl;//step6
// //clear check
// s3.clear();
// check(s3,"s3");
// if(s1==s3)
// cout<<"comparison truen";
// else
// cout<<"comparison falsen";
// reserve check
// mystring::size_type res;
// res=40;
s3.reserve(40);//still working on reserve
check(s3,"s3");
cout<<"in main buf size"<<s3.capacity()<<endl;
s3.reserve(5);
check(s3,"s3");
// char* test=s3.begin();
// cout<<&test<<endl;
// cout<<&s3<<endl;
//empty check
// string s4;
//
// if (s4.empty())
// cout<<"Empty is truen";
// else
// cout<<"Empty is falsen";
return 0;
}
#ifndef MYSTRING_H
#define MYSTRING_H
#include <iostream>
#include <math.h>
#include <cstring>
using namespace std;
class mystring {
public:
// types with scope in this class
typedef unsigned int size_type;
typedef char * iterator;
typedef const char * const_iterator;
static const long int npos = 1073741824;
// default constructor
mystring();//good
// other constructors
mystring(const char *);//good
// copy constructor
mystring(const mystring& orig);//
// destructor
~mystring();////
// iterators
iterator begin();//good
iterator end();//good
//=== memory related ===
// change buffer size to n
void reserve(size_type n);
size_type size() const;////good returns len
size_type length() const;////good returns len
size_type capacity() const;////good returns buf_size
size_type max_size() const;////good
bool empty() const;////good
//=== overloading operators ===
// assignment operator
mystring& operator=(const mystring&);////
// mystring& operator=(const char *);
// array notation
char operator[](size_type pos) const;
char& operator[](size_type pos);
// append
mystring& operator+=(const mystring& str);
mystring& operator+=(const char * str);
//=== methods that modifiy the string
void clear();////good
void push_back(char c);
mystring& append(const mystring& str);
mystring& append(const char * str);
mystring& insert(size_type pos, const mystring& str);
mystring& insert(size_type pos, const char * str);
mystring& replace(size_type start, size_type span, const mystring& str);
mystring& replace(size_type start, size_type span, const char * str);
//=== conversion to c string
const char * c_str() const;//
private:
// pointer to the memory location where string is stored as a c-style
// string
char * ptr_buffer;
// the size of the memory in terms of bytes or characters capable of going into it currently
size_type buf_size;
// number of characters currently in the memory not including the
// terminating null character
size_type len;
};
#include "mystring.h"
// default constructor provided for lab 5
mystring::mystring() {
ptr_buffer = new char[1];
*ptr_buffer = ' ';
buf_size = 1;
len = 0;
}
// constructor from c-style string or "abc" provided for lab 5
mystring::mystring(const char * s) {
len = strlen(s);
buf_size = len + 1;
ptr_buffer = new char[buf_size];
strcpy(ptr_buffer, s);
}
// copy constructor to be implemented in lab 5
mystring::mystring(const mystring& orig) {
len=orig.length();
ptr_buffer=new char[len+1];
buf_size=len+1;
for(int n=0 ;n<buf_size; n++ )
{
ptr_buffer[n]=orig.ptr_buffer[n];
}
ptr_buffer[buf_size]=' ';
}
void mystring::reserve(size_type n)
{
cout<<"cccccc:"<<capacity()<<endl;
if( n > capacity() )
{
const char* temp = ptr_buffer;
ptr_buffer = new char[n];
memcpy(ptr_buffer, temp, len+1);
delete [] temp;
buf_size=n;
cout<<"bbbbbuf size"<<buf_size<<endl;
}
// char *temp;
//
// temp=new char[n];
//
// int i=0;
//
// for(;i<=len;i++)
// {
// temp[i]=ptr_buffer[i];
//
// }
// buf_size=n;
//
// delete [] ptr_buffer;
//
// ptr_buffer=temp;
//
}
mystring::iterator mystring::begin()//think is working correctly
{
iterator it=ptr_buffer;
return it;
}
mystring::iterator mystring::end()//think is working correctly
{
iterator it=ptr_buffer+len;
return it;
}
// one of the over loaded assignment operator to be implemented // assignment 3 (or for lab 5 if you have more time)
mystring& mystring::operator=(const mystring& orig){
if(this!=&orig)
// {
// cout<<"this==&mystring if statment activatedn";//comment out after testing
// break;
// }
{
delete this->ptr_buffer;
this->len=orig.len;//length();
this->ptr_buffer=new char((this->len)+1);
this->buf_size=(this->buf_size)+1;
cout<<"Using assignment operator="<<endl;
for(int n=0;n<this->buf_size;n++)
{
this->ptr_buffer[n]=orig.ptr_buffer[n];
}
this->ptr_buffer[buf_size]=' ';
return *this;
}
}
// some simple methods provided for lab 5
mystring::size_type mystring::size() const {
return len;
}
mystring::size_type mystring::length() const{
return len;
}
mystring::size_type mystring::capacity() const{
return buf_size;
}
mystring::size_type mystring::max_size() const{
return (int)pow(2,30) -4 ;
}
bool mystring::empty() const
{
if(len==0)
return true;
else
return false;
}
// destructor to free space implemented for lab 5
mystring::~mystring() {
delete [] ptr_buffer;
}
// provided for lab 5 so we may cout mystring
ostream& operator<<(ostream& out, const mystring& str) {
out << str.c_str();
return out;
}
// provided for lab 5 to support the implementation of <<
const char * mystring::c_str() const {
return ptr_buffer;
}
char mystring::operator[](size_type pos) const
{
return *(ptr_buffer+pos);
}
void mystring::clear()
{
char *temp;
temp=new char[1];
temp[0]=' ';
ptr_buffer=temp;
buf_size=0;
len=0;
}
void mystring::push_back(char c)
{
}
bool operator==(const mystring& lhs, const mystring& rhs)
{
if(lhs.length()==rhs.length())
{
for(int i=0; i<lhs.length();i++)
{
if(lhs[i]!=rhs[i])
return false;
}
return true;
}
return false;
}
所以我在reserve()
函数和main中放了一些cout语句。保留函数正在更改缓冲区大小,并且容量调用正在正确返回,但是当我们使用检查函数时,它没有显示发生了任何更改。我已经输入了修改后的代码。
好的,每一个人。结果,在main之前声明的检查函数生成了mystring
对象的副本。复制构造函数定义为使buf_size= len + 1
。所以我把它变成了buf_size=orig.buf_size
。储备函数可能像说的那样工作是的,它需要一个if语句来确保我们没有缩小它,但我还不担心这个。我使用了dave的例子并添加了一些代码。谢谢大家的帮助。
void mystring::reserve(size_type n)
{
if (n <= buf_size)
{
return;
}
from MSDN basic_string::reserve Sets the capacity of the string to a number at least as great as a specified number.
所以reserve
不能用来截断字符串
这里我们做了一些更强大的事情(我们不让"用户"缩短缓冲区)。显然你可以
if (n <= len + 1) // remember the terminator is not included in len
{
return;
}
,它将是正确的。
但即使第一种形式也是正确的。不能保证reserve
会"减小"缓冲区的大小。
一般来说,要在缓冲区之间复制,应该使用memcpy
,长度为len + 1
。它(通常)更快(没有人要求更快,但它是更快:-))
- cppcheck在const std::string[]上引发警告
- 将std::string传递给WriteConsole API
- 为std::string的某个索引赋值
- std中有类似find_last_of的函数,而string中没有
- 使用 std::string () const 函数启动线程或未来
- 使用char类型将decimal转换为string,将string转换为decimal
- 迭代和比较映射<字符串、矢量<string>> c++ 中的值
- 当我们进行一些操作时,应该使用什么'std::string'或'std::stringstream'?
- 将向量解析<string>为字符串
- 'string.assign(string.data(), 5)' 是明确定义的还是 UB?
- 如何更改大小(std::string)
- "string.h"在构建适用于iOS的qt应用程序中找不到消息
- C++:如何将 unix 时间的字符串转换为 *tm?(使用时间错误:"cannot convert 'String' to 'tm*' ")
- std::string::reserve没有被允许创建具有精确容量的std::string
- 使用具有 string.reserve() 的字符串实例化结构
- std::string::reserve 是否会更改 std::string 的大小
- 为什么"std::string::reserve()"不保留我指定的确切空间量?
- 用户自定义string::reserve()
- The usage of string::reserve
- std::string::reserve() and std::string::clear() conundrum