2016-09-18 13 views
5

Tôi đã đoạn mã sau:Chuyển đổi char * để chuỗi &

#include <iostream> 
using namespace std; 

int main(int argc, char *argv[]) 
{ 
    string &s1 = argv[0];   // error 
    const string &s2 = argv[0];  // ok 

    argv[0] = "abc"; 
    cout << argv[0] << endl;  // prints "abc" 
    cout << s2 << endl;    // prints program name 
} 

tôi nhận được lỗi sau cho s1:

invalid initialization of reference of type 'std::string& {aka std::basic_string<char>&}' from expression of type 'char*' 

Thế thì tại sao các trình biên dịch chấp nhận s2?

Điều thú vị là khi tôi chỉ định giá trị mới cho argv[0] thì s2 không thay đổi. Liệu trình biên dịch bỏ qua rằng đó là một tài liệu tham khảo và sao chép giá trị nào? Tại sao nó lại xảy ra?

Tôi viết điều này trong Mã :: Khối 16.01 (mingw). Điều tương tự cũng xảy ra với/không có -std=c++11.

+1

Bạn có thể nói rằng 'argv [0]' là một 'std :: string'? – Biffen

+0

"Vậy tại sao trình biên dịch lại chấp nhận s2?" vì chuyển đổi tiềm ẩn. http://stackoverflow.com/questions/4553896/conversion-of-char-to-string –

Trả lời

6

Sau đó, tại sao trình biên dịch chấp nhận s2?

Do tham chiếu không đổi có thể liên kết với tạm thời và std::string có hàm tạo có thể lấy một tham số char *.

Bài tập đó tạo nên một đối tượng "tạm thời", và liên kết một tham chiếu liên tục với nó.

Điều thú vị là khi tôi chỉ định giá trị mới cho argv [0] thì s2 không thay đổi .

Tại sao nó nên thay đổi? s2 là một đối tượng riêng biệt. Đối tượng std::string không duy trì con trỏ đến số char * đã tạo ra đối tượng đó. Có nhiều cách để tạo một std::string. Chuỗi thực tế được sở hữu bởi đối tượng. Nếu số std::string được tạo từ một chuỗi ký tự chữ, nó sẽ được sao chép vào std::string. Vì vậy, nếu chuỗi ký tự chữ đến từ một bộ đệm, và bộ đệm được sửa đổi sau đó, nó không có hiệu lực trên std::string.

+0

Hàm tạo của 'std :: string' lấy một' const char * 'cho tham số. Liệu tôi có sai? – skypjack

+0

Không, bạn không, @skypjack. Đó là lý do tại sao tôi đã viết "có thể mất", thay vì "mất". –

5

dòng này:

const string &s2 = argv[0]; 

Tạo một string dụ mới, sao chép nội dung của argv[0], và liên kết với các tham chiếu đến nó. Sau đó, bản sao này được xuất, hiện không liên quan đến giá trị thực tế của argv[0].

Vòng đời đối tượng chuỗi tạm thời, được tạo trong dòng được trích dẫn, được mở rộng đến phạm vi của khối, vì tham chiếu const được tạo thành nó. Xem thêm tại: Does a const reference prolong the life of a temporary?

+0

Cảm ơn bạn đã liên kết! –

1

Trong cả hai trường hợp, mã yêu cầu trình biên dịch tạo đối tượng std::string tạm thời có nội dung là bản sao argv[0]. Trong khi đó là niềm vui và có thể hữu ích để xem chi tiết của một trong những công trình và tại sao, về mặt thực tế viết mã, rối tung xung quanh với thời gian là không cần thiết và dẫn đến sự nhầm lẫn.Chỉ cần tạo một đối tượng:

std::string s1 = argv[0]; 
1

Dòng

const string &s2 = argv[0]; 

bằng:

const string &s2 = std::string(argv[0]); 

Vì vậy s2 chứa một tham chiếu const thành một chuỗi tạm thời, mà sao chép nội dung từ argv [ 0].

Các vấn đề liên quan