C ++入門書の5番目のメモ(第13章コピー制御)参照修飾子

1.問題

右辺値と左辺値の参照メンバー関数に関して、メンバー関数は通常、オブジェクトが左辺値であるか右辺値であるかに関係なく、オブジェクトで呼び出されます。

string s1 = "a value",s2 = "another";
auto n = (s1 + s2).find('a');
 
s1 + s2 = "wow";

2.定義

上記の式は右辺値を割り当てます。この式を防ぐために、新しい標準では、パラメータリスト修飾子の後に参照を配置することにより、左のオペランド(this)が指すオペランドを強制的に左辺値にすることができます。

class Foo {
    
    
public:
	Foo& operator=(const Foo&)& {
    
    
		return *this;
	}
	Foo& retFoo() {
    
    
		;	//返回一个引用,retFoo调用是一个左值 
		return *this;
	}

	Foo retVal() {
    
    
		;	//返回一个值,retVal调用是一个右值 
		return Foo();
	}
};

その後、

Foo i, j;	//i,j是左值
i = j;
retFoo() = j;	//正确,retFoo()返回一个左值
retVal() = j;	//错误,retVal()返回一个右值
i = retVal();	//正确
j= retFoo();	//正确

2.1 &&を使用して、「左側のオペランドは右辺値です」を強制的に指定できます。

inline void StrVec::push_back(std::string &&s) 
{
    
    
    chk_n_alloc(); // reallocates the StrVec if necessary
	alloc.construct(first_free++, std::move(s));
}

2.2 const修飾子と同様に、参照修飾子は非静的メンバー関数にのみ使用できます

2.3関数の宣言と定義に同時に現れる必要があります。

3.constおよび参照修飾子

関数はconst修飾子と参照修飾子の両方を使用できます。この場合、参照修飾子はconst修飾子の後に続く必要があります。

class Foo{
    
    
public:
	Foo someMes() & const; 	//错误,const限定符必须在前
	Foo someMes() const &; 	//正确,const限定符必须在前
};

データメンバーを変更しない関数は、const型として宣言する必要があります。

4.過負荷

4.1定義

参照修飾子は、オーバーロードされたバージョンを区別するために使用できます。「&&は、戻り値が右辺値であることを示します」。また、参照修飾子とconstを組み合わせて、メンバー関数のオーバーロードされたバージョンを区別できます。

class Foo{
    
    
public:
	Foo sorted() &&;	//可用于改变的右值
	Foo sorted() const &;	//可用于任何类型的Foo
private:
	vector<int> data;
};

//本对象是右值,因此可以原址排序
Foo Foo::sorted() &&
{
    
    
	sort(data.begin(),data.end());
	return *this;
}

//本对象是const或是一个左值,哪种情况我们都不能对其进行原址排序
Foo Foo::sorted() const &
{
    
    
	Foo ret*(*this);			//拷贝一个副本
	sort(ret.begin(),ret.end());	//排序副本
	return ret;	//返回副本
} 
retVal.sorted();	//retVal()是一个右值,调用Foo::sorted() &&
retFoo.sorted();	//retFoo()是一个左值,调用Foo::sorted() const &

4.2使用制限

  • constメンバー関数を定義する場合、2つのバージョンを定義できます。唯一の違いは、一方のバージョンはconst修飾されており、もう一方はそうではないことです。
  • 参照修飾関数は同じではありません。同じ名前と同じパラメーターリストを持つ2つ以上のメンバー関数を定義する場合は、すべての関数に参照修飾子を追加する必要があります。追加しない場合は、次のようにします。
class Foo
{
    
    
	Foo sorted() &&;
	Foo sorted() const;	//错误,必须加上引用限定符
	using Comp = bool (const int&,const int&);
	Foo sorted(Comp*);	//正确,不同的参数列表
	Foo sorted(Comp*);	//正确,两个版本都没有使用引用限定符
};

おすすめ

転載: blog.csdn.net/thefist11cc/article/details/113914161