C++ Primer第十三章⑧

C++ Primer

拷贝控制

对象移动

我们一般会同时定义拷贝和移动两个操作,这样好处大大滴,以push_back函数为例:

void push_back(const X&); //拷贝:可以绑定到任意类型的X(因为加了const)
void push_back(X&&); //移动:只能绑定到类型为X的可修改的右值

区分移动和拷贝的重载函数通常有两个版本:一个接受const T&,另一个接受T&&

再来个具体的例子:

class StrVec
{
public:
    void push_back(const string&); //拷贝元素
    void push_back(string&&); //移动元素
};

void StrVec::push_back(const string& s)
{
    chk_n_alloc(); //确保有新空间
    alloc.construct(first_free++, s); //插入s,并后移first_free
}
void StrVec::push_back(string&& s)
{
    chk_n_alloc(); //确保有新空间
    alloc.construct(first_free++, std::move(s)); //插入s,并后移first_free
}

写完后我们来调用试试:

StrVec vec; 
string s = "some thing";
vec.push_back(s); //调用push_back(const string&),是拷贝的,s可能还要用的
vec.push_back("done"); //调用push_back(string&&),是移动的,"done"就不用了
来看点关于左值和右值神奇的东西

我们来看点看上去非法的,但是编译器不会报错的:

string s1 = "a", s2 = "b";
auto n = (s1+s2).find('a'); //我们居然在一个右值上调用函数,右值代表值啊,
然而这是可以的。。。主要是因为新旧标准问题
s1 + s2 = "fff"; //这也行的。。。

在新标准中,向右值赋值还是算合法的。。。
我们虽然不能去动标准库(它是允许向右值赋值的),但是我们可以在自己的地盘自己定义的类中阻止这种不合理的方式-我们希望强制左侧运算对象(this)是一个左值。

那我们具体该怎么做呢?我们可以在赋值运算符参数列表后面加一个引用限定符,&表示this指向左值,&&表示右值;而且,引用限定符只能用于(非static)成员函数,且必须同时出现在函数的声明和定义中:

class Foo
{
public:
    Foo &operator=(const Foo&) &; //拷贝赋值运算符,且只能给左值赋值
};
Foo &Foo::operator(const Foo &rhs) & //声明和定义中都要有引用限定符
{
    return *this;
}

好的,我们来用下试试:

Foo &retFoo(); //函数声明,返回引用,是左值
Foo retVal(); //返回右值
Foo i, j;
i = j; //正确:i是左值
retFoo() = j; //正确:retFoo返回左值
retVal() = j; //错误
i = retVal(); //正确

记不记得我们还可以在参数列表后面放const,表示该函数不能修改类中的成员变量,我们得把&放在const之后:

Foo anothr() const &{};
重载

我们直接抛代码:

class Foo
{
public:
    Foo sorted() &&; //用于可改变的右值
    Foo sorted() const &; //可用于任意类型的Foo
private:
    vector<int> data;
}
Foo Foo::sorted() &&
{
    sort(data.begin(), data.end());
    return *this;
}
Foo Foo::sorted() const &
{
    Foo ret(*this); //我们无法改变this,所以要拷贝个副本来排序返回
    sort(ret.data.begin(), ret.data.end());
    return ret
}

编译器会通过函数匹配来确定调用哪个:

retVal().sorted(); //retval()返回右值,调用Foo::sorted() &&
retFoo().sorted(); //调用左值那个

注意,引用限定符是这样的,重载函数,要不你都加,要不就都不加,非常讲义气。

全部评论

相关推荐

ResourceUtilization:你是我见过最美的牛客女孩
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务