C++ chuyển đối tượng lớp theo tham chiếu
main() { int i = 10, j = 20; swapThemByVal(i, j); cout << i << " " << j << endl; // displays 10 20 swapThemByRef(i, j); cout << i << " " << j << endl; // displays 20 10 ... } void swapThemByVal(int num1, int num2) { int temp = num1; num1 = num2; num2 = temp; } void swapThemByRef(int& num1, int& num2) { int temp = num1; num1 = num2; num2 = temp; } Có bốn cách truyền đối tượng cho hàm. Giả sử bạn có một lớp X và muốn chuyển nó cho một hàm fun, sau đó Show
Vượt qua giá trịĐiều này tạo ra một bản sao nông cục bộ của đối tượng trong phạm vi chức năng. Những thứ bạn sửa đổi ở đây sẽ không được phản ánh trong đối tượng được truyền cho nó. Ví dụ, Tuyên ngônvoid fun(X x); gọiX x; fun(x); Vượt qua tham khảoĐiều này chuyển một tham chiếu đến đối tượng đến hàm. Những thứ bạn sửa đổi ở đây sẽ được phản ánh trong đối tượng được truyền cho nó. Không có bản sao nào của đối tượng được tạo. Ví dụ, Tuyên ngônvoid fun(X &x); gọiX x; fun(x); Vượt qua tham chiếu constĐiều này chuyển một tham chiếu const đến đối tượng cho hàm. Bạn không thể trực tiếp sửa đổi/gán lại đối tượng ở đây (bạn có thể sử dụng các phương thức của nó để làm như vậy). Điều này hữu ích nếu bạn muốn chức năng chỉ có một bản sao chỉ đọc của đối tượng. Không có bản sao nào của đối tượng được tạo. Ví dụ, Tuyên ngônvoid fun(X const *x); gọiX x; fun(&x); Vượt qua con trỏ constĐiều này chuyển một con trỏ const tới đối tượng cho hàm. Bạn không thể sửa đổi/gán lại con trỏ ở đây. Điều này hữu ích nếu bạn muốn hàm chỉ có địa chỉ của đối tượng này trong con trỏ. Không có bản sao của đối tượng được tạo ra. Ví dụ, Tuyên ngônvoid fun(X *x); gọiX x; fun(&x); Vượt qua con trỏĐiều này chuyển một con trỏ tới đối tượng tới hàm. Điều này tương tự như chuyển một tham chiếu đến đối tượng. Không có bản sao của đối tượng được tạo ra. Ví dụ, Một lần nữa, bạn có thể thấy từ đầu ra sau rằng X x; fun(x);7 đã được thay đổi bằng cách gọi hàm 0void fun(X x);0 Truyền đối tượng theo tham chiếuGiống như các biến không phải mảng khác, các đối tượng có thể được truyền theo tham chiếu. Ví dụ, đoạn mã chương trình sau void fun(X x);1 Có thể bạn quan tâmsẽ tạo ra đầu ra này void fun(X x);2 Việc truyền các đối tượng C++ bằng tham chiếu là cực kỳ phổ biến ngay cả khi một hàm không cần thay đổi đối tượng ban đầu trong quy trình gọi. Các đối tượng thường có thể khá lớn, vì vậy việc chuyển chúng theo giá trị có thể tốn kém về dung lượng bộ nhớ mà chúng chiếm và thời gian cần thiết để tạo một bản sao của chúng. Ngược lại, các tham chiếu (con trỏ ẩn) rất nhỏ và có kích thước cố định (thường là 4 hoặc 8 byte). Truyền đối tượng theo tham chiếu thường sẽ giúp chúng ta tiết kiệm cả bộ nhớ và thời gian Nhược điểm duy nhất của việc truyền một đối tượng bằng tham chiếu là hàm sẽ có thể thay đổi đối tượng ban đầu đã được truyền cho nó. Đó là điều không mong muốn. Nếu một chức năng không cần thay đổi một đối tượng, lý tưởng nhất là chúng tôi muốn làm như vậy là không thể Hơn nữa, nếu chúng ta cố truyền một đối tượng hằng bằng tham chiếu, trình biên dịch sẽ tạo ra lỗi cú pháp. Ví dụ: nếu bạn cố gắng biên dịch mã chương trình sau trên 1 thành 2void fun(X x);5 trình biên dịch sẽ tạo ra lỗi cú pháp sau void fun(X x);6 Thông báo lỗi này đề cập đến "vòng loại" là vòng loại 3 trong phần khai báo của biến 4 5. Về cơ bản, trình biên dịch đang nói với chúng ta rằng "biến này mà bạn đang chuyển đến hàm 6 là hằng số nhưng bạn đang chuyển nó theo cách cho phép hàm thay đổi nó. "Tham chiếu đến các biến không đổiĐể khắc phục sự cố đó, chúng ta có thể sử dụng tham chiếu đến một biến không đổi. Điều này tạo ra một tham chiếu không thể được sử dụng để sửa đổi biến mà nó đề cập đến. Ví dụ: đoạn mã sau sẽ biên dịch mà không có bất kỳ lỗi cú pháp nào X x; fun(x);1 Lưu ý rằng trình biên dịch C++ không phàn nàn nếu bạn truyền một đối tượng không cố định cho một hàm bằng cách sử dụng tham chiếu đến một đối tượng không đổi. Điều đó đơn giản có nghĩa là hàm sẽ không thể thay đổi đối tượng ban đầu trong quy trình gọi bằng cách sử dụng tham chiếu, mặc dù đối tượng ban đầu không phải là hằng số Như một quy tắc chung Nếu bạn muốn một hàm hoặc hàm thành viên có thể thay đổi một đối tượng C++, hãy chuyển nó bằng tham chiếu Nếu bạn không muốn một hàm hoặc hàm thành viên có thể thay đổi một đối tượng C++, hãy chuyển nó dưới dạng tham chiếu đến một biến không đổi Hầu hết thời gian, không có lợi ích thực sự nào khi chuyển một biến thuộc loại tích hợp sẵn như 7 hoặc 8 bằng cách sử dụng tham chiếu đến một biến không đổi. Nếu bạn không muốn một hàm sửa đổi biến ban đầu trong thói quen gọi, chỉ cần chuyển biến theo giá trịTrả lại tài liệu tham khảoCác hàm thành viên đôi khi cũng có thể trả về một biến hoặc đối tượng theo tham chiếu hoặc trả về một tham chiếu cho một biến không đổi. Điều này thường được thực hiện nhất nếu hàm thành viên trả về đối tượng đã gọi nó, trả về tham số hàm chính nó là tham chiếu hoặc trả về thành viên dữ liệu là đối tượng Việc trả về một tham chiếu đến một biến cục bộ tự động được khai báo bên trong một hàm thường là một lỗi. Biến cục bộ sẽ tự động được hủy cấp phát khi chức năng kết thúc và mã gọi sẽ được để lại với tham chiếu đến một biến không còn tồn tại Tài liệu tham khảo so với con trỏTham chiếu C++ khác với con trỏ ở một số điểm cơ bản
Thông thường, trình biên dịch C++ sẽ coi một tham chiếu là bí danh đơn giản cho biến mà nó đề cập đến (giả sử biến đó được khai báo trong cùng một phạm vi) hoặc biên dịch tham chiếu thành một con trỏ được hủy đăng ký hoàn toàn mỗi khi sử dụng tham chiếu đó. Cú pháp cần thiết để sử dụng con trỏ có xu hướng làm cho chúng nổi bật; . Trong một khối mã C++ lớn, có thể không phải lúc nào cũng rõ ràng liệu một biến đang được truy cập được định nghĩa là biến cục bộ hay biến toàn cục hay liệu nó có phải là một tham chiếu đến một biến ở một số vị trí khác hay không, đặc biệt nếu mã trộn lẫn các tham chiếu và con trỏ. Điều đó có thể làm cho mã C++ được viết kém khó đọc và gỡ lỗi hơn Tuy nhiên, do các thao tác được phép trên các tham chiếu rất hạn chế nên chúng dễ hiểu hơn nhiều so với con trỏ và có khả năng chống lỗi cao hơn. Mặc dù con trỏ có thể bị làm cho không hợp lệ thông qua nhiều cơ chế khác nhau, từ việc mang giá trị null đến số học ngoài giới hạn đến ép kiểu không hợp lệ để tạo ra chúng từ các số nguyên ngẫu nhiên, một tham chiếu hợp lệ trước đó chỉ trở nên không hợp lệ trong hai trường hợp
Nói chung, nếu chúng ta cần thay đổi giá trị của một đối số không phải mảng được truyền cho một hàm, chúng ta sẽ truyền nó theo tham chiếu. Tuy nhiên, có một số trường hợp bạn không có lựa chọn nào khác ngoài việc truyền đối số theo địa chỉ hoặc sử dụng con trỏ
Để được coi là một lập trình viên C++ có năng lực, cần phải hiểu về cả cơ chế chuyển qua địa chỉ và tham chiếu qua tham chiếu. Bạn có thể chuyển một đối tượng bằng tham chiếu không?Giá trị của một đối tượng có thể thay đổi có thể được thay đổi khi nó được truyền vào một phương thức. Không thể thay đổi giá trị của đối tượng bất biến, ngay cả khi nó được truyền một giá trị mới. "Chuyển theo giá trị" đề cập đến việc chuyển một bản sao của giá trị. “Truyền theo tham chiếu” có nghĩa là truyền tham chiếu thực của biến vào bộ nhớ .
Bạn sẽ truyền đối tượng vào hàm bằng tham chiếu như thế nào?Truyền theo tham chiếu có nghĩa là chuyển tham chiếu của một đối số trong hàm gọi đến tham số hình thức tương ứng của hàm được gọi . Hàm được gọi có thể sửa đổi giá trị của đối số bằng cách sử dụng tham chiếu của nó được truyền vào. Ví dụ sau đây cho thấy cách các đối số được truyền bằng tham chiếu.
Chuyển qua tham chiếu có sẵn trong C không?Truyền bằng tham chiếu đề cập đến một phương thức truyền địa chỉ của một đối số trong hàm gọi đến một tham số tương ứng trong hàm được gọi. Trong C, tham số tương ứng trong hàm được gọi phải được khai báo là kiểu con trỏ .
Truyền một đối tượng bằng cách tham chiếu có nghĩa là gì?Xác định Vượt qua theo Tham chiếu
. Theo tham chiếu có nghĩa là đối số bạn đang chuyển đến hàm là tham chiếu đến một biến đã tồn tại trong bộ nhớ chứ không phải là bản sao độc lập của biến đó. to provide an argument to a function. By reference means that the argument you're passing to the function is a reference to a variable that already exists in memory rather than an independent copy of that variable. |