C++:C++的string类的构造函数及对象之间的比较

来源:互联网 发布:视频录制软件 编辑:程序博客网 时间:2024/06/06 01:53

头文件:

#inlcude <string>

下表有string的7个构造函数及C++11新增的2个构造函数;


一,下例是几种string的应用:

#include <iostream>#include <string>int main(){using namespace std;string one("Lottery Winner!");cout << one << endl; // Lottery Winner!string two(20, '$');cout << two << endl; // $$$$$$$$$$$$$$$$$$$$string three(one);cout << three <<endl; // Lottery Winner!one += " Oops!";cout << one << endl; // Lottery Winner Oops!two = "Sorry! That was ";three[0] = 'P';string four = two + three;cout << four << endl; // Sorry! That was Pottery Winner!char alls[] = "All's well that ends well";string five(alls, 20);cout << five << "!\n"; // All's well that ends!string six(alls + 6, alls + 10); // 从alls的第6个位置截止至alls的第10个位置cout << six << ", "; // well,string seven(&five[6], &five[10]); //同上cout << seven << "...\n"; // well...string eight(four, 7, 16); // 意思是从four的第7个位置开始数16个放进eightcout << eight << " in motion!" << endl; // That was Pottery in motion! return 0;}
要注意的是:

template<class Type> string(Iter begin, Iter end);

这里[begin, end) 意味着 包括 begin, 不包括 end,如上例中的 six, seven

二,C++新增的构造函数

移动构造函数move constructor的运行原理如下图,在有些情况下,编译器可使用它而不是复制构造函数来优化性能。

用法:string(string && str)

例:

A(A && h) : a(h.a){h.a = nullptr; //还记得nullptr?}
可以看到,这个构造函数的参数不同,有两个&操作符,   移动构造函数接收的是“右值引用”的参数。
还要来说一下,这里h.a置为空,如果不这样做,h.a在移动构造函数结束时候执行析构函数会将我们偷来的内存析构掉。h.a会变成悬垂指针。
这里要注意的是,异常发生的情况,要尽量保证移动构造函数不发生异常,可以通过noexcept关键字,这样可以保证移动构造函数中抛出来的异常会直接调用terminate终止程序。

在c++11中,右值引用就是对一个右值进行引用的类型,右值通常不具有名字,我们就只能通过引用的方式找到它的存在了。
比较一下下面两条语句:

T &&a = returna();  T b = returnb(); 
此时a是右值引用,他比b少了一次对象析构和对象构造的过程。a直接绑定了returna返回的临时变量。b只是由临时变量值构造而成的。
右值引用就是让返回的右值(临时对象)重获新生,延长生命周期。临时对象析构了,但是右值引用存活。
不过要注意的是,右值引用不能绑定左值:int a; int &&c = a;   这样是不行的。

这里有一个函数就是 move函数,它能够将左值强制转换成右值引用。

A & operator = (A&& h){assert(this != &h);a = nullptr;a = move(h.a);h.a = nullptr;return *this;}

构造函数 string(initializer_list<char> il) 可以将列表初始化用于string类

例:

string a = {'L', 'i', 's', 't'};
就string类而说,用处不大,因为使用C-风格字符串更容易。

三,关于string类的输入。

对于C-风格字符串,有三种输入方式:

char info[100];cin >> info; //#1cin.getline(info, 100); // #2 discard \ncin.get(info, 100); // #3 leave \n in queue
对于string对象,有两种输入方式:

string stuff;cin >> stuff;getline(cin, stuff); // discard \n
getline()有一个可选参数,用以确定输入的边界:

但注意的是:指定分界符后,换行符将视为常规字符。

cin.getline(info, 100, ':'); //C-风格字符串getline(stuff, ':'); // string
使用区别:string版的getline()将自动调整目标string 对象的大小,使之刚好能够存储输入的字符,但也不是无限的,

                   第一个限制是string对象的最大允许长度,由常量string::npos指定,这通常是最大的unsigned int 值。

   第二个限制是程序可以使用的内存量。

设计区别:C-风格字符串,cin是调用对象;对string对象,cin是一个函数参数。

string版本的getline()函数从输入中读取字符,并将其存储目标string中,以下三种情况会终止:

1)到达文件尾

2)遇到分界字符(默认\n)

3)读取的字符数达到最大允许值(string::npos 与 可供分配的内存字节数中较小的一个)


string字符串的比较:

string snake1("cobra");string snake2("coral");char snake3[20] = "anaconda";if (snake1 < snake2) // operator<(const string& , const string& )... if (snake1 == snake3) // operator==(const string& , const char* )...if (snake3 != snake2) // operator!=(const char* , const string& )

string字符串的长度:

if (snake1.length() == snake2.size())... 
lengh()来自较早的string类,而size()则是为STL兼容性而添加的。






0 0
原创粉丝点击