Tôi đang học C ++ từ đầu và tôi không nhận được toàn bộ chủ đề về chuỗi.
Sự khác biệt giữa ba mã sau đây là gì?
std::string s = std::string("foo");
std::string s = new std::string("foo");
std::string s = "foo";
Tôi đang học C ++ từ đầu và tôi không nhận được toàn bộ chủ đề về chuỗi.
Sự khác biệt giữa ba mã sau đây là gì?
std::string s = std::string("foo");
std::string s = new std::string("foo");
std::string s = "foo";
std::string s = std::string("foo");
Điều này tạo ra một std::string
đối tượng tạm thời có chứa "foo", sau đó gán nó cho s
. (Lưu ý rằng các trình biên dịch có thể bỏ qua tạm thời. Elison tạm thời trong trường hợp này được tiêu chuẩn C ++ cho phép một cách rõ ràng.)
std::string s = new std::string("foo");
Đây là một lỗi trình biên dịch. Biểu thức new std::string("foo")
tạo một std::string
trên cửa hàng miễn phí và trả về một con trỏ đến một std::string
. Sau đó, nó cố gắng gán con trỏ trả về kiểu std::string*
thành s
kiểu std::string
. Thiết kế của std::string
lớp ngăn điều đó xảy ra, vì vậy quá trình biên dịch không thành công.
C ++ không phải là Java. Đây không phải là cách các đối tượng thường được tạo ra, bởi vì nếu bạn quên đối tượng được delete
trả về, std::string
bạn sẽ làm rò rỉ bộ nhớ. Một trong những lợi ích chính của việc sử dụng std::string
là nó tự động quản lý bộ đệm chuỗi bên dưới cho bạn, vì vậy new
nó loại bỏ mục đích đó.
std::string s = "foo";
Điều này về cơ bản giống với # 1. Về mặt kỹ thuật, nó khởi tạo một chuỗi tạm thời mới chứa "foo", sau đó gán nó cho s
. Một lần nữa, các trình biên dịch thường sẽ loại bỏ tạm thời (và trên thực tế, hầu hết tất cả các trình biên dịch không ngu ngốc hiện nay trên thực tế đều loại bỏ tạm thời), vì vậy trong thực tế, nó chỉ đơn giản là xây dựng một đối tượng mới được gọi s
tại chỗ.
Cụ thể, nó gọi một phương thức khởi tạo chuyển đổi trong std::string
đó chấp nhận một const char*
đối số. Trong đoạn mã trên, hàm tạo chuyển đổi bắt buộc phải là non- explicit
, nếu không thì đó là lỗi trình biên dịch. Hàm tạo chuyển đổi trên thực tế không phải là explicit
for std::string
s, vì vậy ở trên thực hiện biên dịch.
Đây là cách std::string
thường được khởi tạo. Khi s
vượt ra khỏi phạm vi, s
đối tượng sẽ bị phá hủy cùng với bộ đệm chuỗi bên dưới. Lưu ý rằng cách sau cũng có tác dụng tương tự (và là một cách điển hình khác mà std::string
s được khởi tạo), theo nghĩa là nó cũng tạo ra một đối tượng được gọi là s
chứa "foo".
std::string s("foo");
Tuy nhiên, có một sự khác biệt nhỏ giữa std::string s = "foo";
vàstd::string s("foo");
, một trong số chúng là hàm tạo chuyển đổi có thể là explicit
hoặc không explicit
trong trường hợp trên.
std::string s = std::string("foo");
Đây được gọi là khởi tạo sao chép. Nó có chức năng giống như khởi tạo trực tiếp
std::string s( "foo" );
nhưng cái trước yêu cầu phải có sẵn hàm tạo bản sao và các trình biên dịch có thể tạo một đối tượng tạm thời nhưng hầu hết sẽ giải thích cấu trúc tạm thời và trực tiếp s
để chứa "foo"
.
std::string s = new std::string("foo");
Điều này sẽ không biên dịch vì new
trả về một con trỏ. Để làm cho nó làm việc bạn cần loại s
là một std::string *
. Sau đó, dòng tự động cấp phát một std::string
đối tượng và lưu trữ con trỏ vào s
. Bạn sẽ cần delete
nó sau khi sử dụng xong.
std::string s = "foo";
Điều này gần giống như lần đầu tiên. Nó là khởi tạo sao chép nhưng nó có thêm một ràng buộc. Nó yêu cầu rằng std::string
lớp phải chứa một phương thức explicit
khởi tạo không phải là một const char *
. Điều này cho phép trình biên dịch xây dựng ngầm một std::string
đối tượng tạm thời . Sau đó ngữ nghĩa giống hệt trường hợp 1.
s
new std::string("foo")
trả về một con trỏ đến một số bộ nhớ mới được cấp phát. Để điều này hoạt động, bạn nên khai báo s như một con trỏ đến một chuỗi std::string* s
.Bạn nên sử dụng tùy chọn thứ ba trong hầu hết - nếu không phải tất cả - trường hợp.
1 sẽ tạo một biến tạm thời (bên tay phải), sau đó gọi toán tử gán để gán giá trị cho s
2 sẽ tạo một thể hiện của std::string
trên heap và trả về một con trỏ cho nó, và sẽ không thực hiện được việc gán vì bạn không thể gán một con trỏ cho kiểu không phải là con trỏ
3 sẽ xây dựng một chuỗi std :: và khởi tạo nó từ một const char*
Trên số 1, bạn đang tạo một chuỗi tạm thời bằng cách sử dụng hàm tạo và sau đó gán nó cho s. Số 2 thậm chí không biên dịch. Trên số 3, bạn đang tạo một chuỗi mới và sau đó gán giá trị cho nó.