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

头文件:

#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个放进eight
	cout << 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; //#1
cin.getline(info, 100); // #2 discard \n
cin.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兼容性而添加的。






  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值