Nhảy chuyển đến

Trích dẫn

Trích dẫn có thể xem thành là C++ phong trang kim đồng hồ, dùng để truyền lại nó sở chỉ hướng đối tượng. Ở C++ số hiệu trung trên thực tế sẽ thường xuyên cùng trích dẫn giao tiếp, nhưng là thông thường sẽ không hiện thức mà biểu hiện ra tới. Trích dẫn cơ bản nguyên tắc là ở thanh minh khi cần thiết chỉ hướng đối tượng, cùng với đối trích dẫn hết thảy thao tác đều tương đương với đối nguyên đối tượng thao tác. Mặt khác, trích dẫn không phải đối tượng, bởi vậy không tồn tại trích dẫn số tổ, vô pháp thu hoạch trích dẫn kim đồng hồ, cũng không tồn tại trích dẫn trích dẫn.

Chú ý trích dẫn loại hình không thuộc về đối tượng loại hình, cho nên mới yêu cầureference_wrapperLoại này phương tiện.

Trích dẫn chủ yếu chia làm hai loại, tả giá trị trích dẫn cùng hữu giá trị trích dẫn. Ngoài ra còn có hai loại đặc thù trích dẫn: Chuyển phát trích dẫn cùng rũ huyền trích dẫn, không làm kỹ càng tỉ mỉ giới thiệu. Mặt khác, bổn văn còn liên lụy tới một bộ phận thường giá trị nội dung, thỉnh dùngThường giá trịMột văn phụ trợ đọc.

Tả giá trị trích dẫn

Tả giá trị cùng hữu giá trị

Nếu ngươi không biết cái gì là tả giá trị cùng hữu giá trị, có thể tham khảoGiá trị phân loạiGiao diện.

Tả giá trị biểu đạt thức

Nếu một cái biểu đạt thức phản hồi chính là tả giá trị, như vậy cái này biểu đạt thức được xưng là tả giá trị biểu đạt thức. Hữu giá trị biểu đạt thức cũng thế.

Thông thường chúng ta sẽ tiếp xúc đến trích dẫn vì tả giá trị trích dẫn, tức trói định đến tả giá trị trích dẫn, nhưngconstTả giá trị trích dẫn có thể trói định đến hữu giá trị. Dưới là đến từTham khảo sổ tayMột đoạn thí dụ mẫu số hiệu.

1
2
3
4
5
6
7
8
9
10
11
12
#include&LTiostream>
#include&LTstring>

intmain(){
std::strings="Ex";
std::string&r1=s;
conststd::string&r2=s;

r1+="ample";// sửa chữa r1, tức sửa chữa s
// r2 += "!"; // sai lầm: Không thể thông qua đến const trích dẫn sửa chữa
std::coutr2'\n';// đóng dấu r2, phỏng vấn s, phát ra "Example"
}

Tả giá trị trích dẫn nhất thường dùng địa phương là hàm số tham số, thông qua tả giá trị trích dẫn truyền tham có thể khởi đến cùng thông qua kim đồng hồ truyền tham tương đồng hiệu quả.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include&LTiostream>
#include&LTstring>

// tham số trung s là trích dẫn, ở thuyên chuyển hàm số khi sẽ không phát sinh copy
char&char_number(std::string&s,std::size_tn){
s+=s;// 's' cùng main() 'str' là cùng đối tượng
// nơi này còn nói minh tả giá trị cũng là có thể đặt ở ngang bằng phía bên phải
returns.at(n);// string::at() phản hồi char trích dẫn
}

intmain(){
std::stringstr="Test";
char_number(str,1)='a';// hàm số phản hồi là tả giá trị, nhưng bị phú giá trị
std::coutstr'\n';// nơi này phát ra "TastTest"
}

Hữu giá trị trích dẫn (C++ 11)

Hữu giá trị trích dẫn là trói định đến hữu giá trị trích dẫn. Hữu giá trịCó thể ở bên trong tồn cũng có thể ở CPU gởi lại khí trung.Mặt khác, hữu giá trị trích dẫn có thể bị coi như một loạiKéo dài lâm thời đối tượng sinh tồn kỳ phương thức.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include&LTiostream>
#include&LTstring>

intmain(){
std::strings1="Test";
// std::string&& r1 = s1; // sai lầm: Không thể trói định đến tả giá trị

conststd::string&r2=s1+s1;// được không: Đến thường giá trị tả giá trị trích dẫn kéo dài sinh tồn kỳ
// r2 += "Test"; // sai lầm: Không thể thông qua đến thường giá trị trích dẫn sửa chữa

std::string&&r3=s1+s1;// được không: Hữu giá trị trích dẫn kéo dài sinh tồn kỳ
r3+="Test";// được không: Có thể thông qua đến phi thường giá trị hữu giá trị trích dẫn sửa chữa
std::coutr3'\n';
}

Ở kể trên số hiệu trung,r3Là một cái hữu giá trị trích dẫn, trích dẫn chính là hữu giá trịs1 + s1.r2Là một cái tả giá trị trích dẫn, có thể phát hiệnHữu giá trị trích dẫn có thể chuyển vì const tân trang tả giá trị trích dẫn.

Một ít ví dụ

++iCùngi++

++iCùngi++Là điển hình tả giá trị cùng hữu giá trị.++iThực hiện là trực tiếp cấp i lượng biến đổi thêm một, sau đó phản hồi i bản thân. Bởi vì i là nội tồn trung lượng biến đổi, bởi vậy có thể là tả giá trị. Trên thực tế trước tự tăng hàm số ký tên làT& T::operator++();.Mài++Tắc không giống nhau, nó thực hiện là dùng lâm thời lượng biến đổi tồn hạ i, sau đó lại đối i thêm một, phản hồi chính là lâm thời lượng biến đổi, bởi vậy là hữu giá trị. Sau tự tăng hàm số ký tên làT T::operator++(int);.

1
2
3
4
5
6
7
8
intn1=1;
intn2=++n1;
intn3=++++n1;// bởi vì là tả giá trị, cho nên có thể tiếp tục thao tác
intn4=n1++;
// int n5 = n1++ ++; // sai lầm, vô pháp thao tác hữu giá trị
// int n6 = n1 + ++n1; // chưa định nghĩa hành vi
int&&n7=n1++;// lợi dụng hữu giá trị trích dẫn kéo dài sinh mệnh kỳ
intn8=n7++;// n8 = 5

Di động ngữ nghĩa cùngstd::move(C++11)

Ở C++11 lúc sau, C++ lợi dụng hữu giá trị trích dẫn tân tăng di động ngữ nghĩa duy trì, dùng để tránh cho đối tượng ở đôi không gian phục chế ( nhưng là vô pháp tránh cho sạn không gian phục chế ), STL vật chứa đối nên đặc tính có hoàn chỉnh duy trì. Cụ thể đặc tính cóDi động cấu tạo hàm số,Di động phú giá trịCùng có di động năng lực hàm số ( tham số đựng hữu giá trị trích dẫn ). Mặt khác,std::moveHàm số có thể dùng để sinh ra hữu giá trị trích dẫn, yêu cầu bao hàm&LTutility>Đầu văn kiện.

Chú ý: Một cái đối tượng bị di động sau không ứng đối này tiến hành bất luận cái gì thao tác, vô luận là sửa chữa vẫn là phỏng vấn.Bị di động đối tượng ở vào hữu hiệu nhưng chưa chỉ định trạng thái, nội dung cụ thể ỷ lại với stl thực hiện. Nếu yêu cầu phỏng vấn ( tức chỉ định một loại trạng thái ), có thể sử dụng nên đối tượngswapThành viên hàm số hoặc là thiên đặc hoástd::swapTrao đổi hai cái đối tượng ( đồng dạng có thể tránh cho đôi không gian phục chế ).

1
2
3
4
5
6
7
8
9
10
11
12
// di động cấu tạo hàm số
std::vectorint>v{1,2,3,4,5};
std::vectorint>v2(std::move(v));// di động v đến v2, không phát sinh copy

// di động phú giá trị hàm số
std::vectorint>v3;
v3=std::move(v2);

// có di động năng lực hàm số
std::strings="def";
std::vectorstd::string>numbers;
numbers.push_back(std::move(s));

Chú ý kể trên số hiệu chỉ ở C++11 lúc sau nhưng dùng.

Hàm số phản hồi trích dẫn

Làm hàm số phản hồi trích dẫn giá trị có thể tránh cho hàm số ở phản hồi khi đối phản hồi giá trị tiến hành copy, như

1
char&get_val(std::string&str,intindex){returnstr[index];}

Ngươi không thể phản hồi ở hàm số trung bộ phận lượng biến đổi trích dẫn, nếu nhất định phải ở hàm số nội lượng biến đổi. Thỉnh sử dụng động thái nội tồn. Tỷ như như sau hai cái hàm số đều sẽ sinh ra huyền rũ trích dẫn, dẫn tới chưa định nghĩa hành vi.

1
2
3
4
5
6
7
8
9
std::vectorint>&getLVector(){// sai lầm: Phản hồi bộ phận lượng biến đổi tả giá trị trích dẫn
std::vectorint>x{1};
returnx;
}

std::vectorint>&&getRVector(){// sai lầm: Phản hồi bộ phận lượng biến đổi hữu giá trị trích dẫn
std::vectorint>x{1};
returnstd::move(x);
}

Đương hữu giá trị trích dẫn chỉ hướng không gian ở tiến vào hàm số trước đã phân phối khi, hữu giá trị trích dẫn có thể tránh cho phản hồi giá trị copy.

1
2
3
4
5
6
7
8
9
structBeta{
Beta_abab;

Beta_abconst&getAB()const&{returnab;}

Beta_ab&&getAB()&&{returnstd::move(ab);}
};

Beta_abab=Beta().getAB();// nơi này là di động ngữ nghĩa, mà phi copy

Tham khảo nội dung

  1. C++ ngôn ngữ hồ sơ —— trích dẫn thanh minh
  2. C++ ngôn ngữ hồ sơ —— giá trị phân loại
  3. Is returning by rvalue reference more efficient?
  4. Thiển nói giá trị phân loại và lịch sử