Các đối tượng có thể được truyền theo giá trị trong C++ không?

Khi bạn chuyển một đối số bằng tham chiếu, bạn chuyển một con trỏ tới giá trị trong bộ nhớ. Hàm hoạt động trên đối số. Khi một hàm thay đổi giá trị của một đối số được truyền bởi tham chiếu, giá trị ban đầu sẽ thay đổi

  • Theo giá trị

    Khi bạn chuyển một đối số theo giá trị, bạn chuyển một bản sao của giá trị đó vào bộ nhớ. Chức năng hoạt động trên bản sao. Điều này có nghĩa là khi một hàm thay đổi giá trị của một đối số được truyền theo giá trị, hiệu ứng sẽ là cục bộ đối với hàm đó;

  • Việc một đối số được truyền theo tham chiếu hay theo giá trị tùy thuộc vào kiểu dữ liệu và các đặc điểm khác của đối số

    • Mảng, danh sách, thể hiện kiểu và đối tượng phải được chuyển qua tham chiếu

    Ghi chú. Tham số mảng không được khai báo là "ByVal"; .

    • Các hằng số và biểu thức được tự động truyền theo giá trị
    • Các đối số khác có thể được chuyển theo một trong hai cách, như được chỉ định trong định nghĩa hoặc lệnh gọi. Các đối số cho hàm và phụ được truyền theo tham chiếu trừ khi định nghĩa hoặc lệnh gọi chỉ định truyền theo giá trị

    Chuyển qua tham chiếu

    Biến phải có cùng kiểu dữ liệu với tham số tương ứng trong định nghĩa hàm, trừ khi tham số được khai báo là Variant hoặc là biến đối tượng. Một biến đối tượng có thể được truyền cho một đối tượng của cùng một lớp cơ sở hoặc lớp dẫn xuất. Sau này, lớp cơ sở phải chứa một thể hiện của lớp dẫn xuất hoặc một lớp dẫn xuất từ ​​lớp dẫn xuất

    Nếu sau đó biến được sửa đổi bởi hàm hoặc phụ, thì biến đó có giá trị được sửa đổi khi hàm hoặc phụ trả về

    Truyền theo giá trị

    Bạn có thể làm như sau

    • Sử dụng từ khóa ByVal trong khai báo của đối số trong hàm hoặc định nghĩa phụ

      Đối số được truyền theo giá trị bất cứ khi nào hàm hoặc phụ được gọi

    • Chèn dấu ngoặc đơn xung quanh đối số trong hàm hoặc lệnh gọi phụ

      Bạn có thể kiểm soát xem một đối số được truyền theo tham chiếu hay theo giá trị tại thời điểm hàm hoặc phụ được gọi

    Một giá trị được chuyển đến một hàm hoặc đối số phụ sẽ tự động được chuyển đổi thành kiểu dữ liệu của hàm hoặc đối số phụ nếu có thể chuyển đổi. Đối số Biến thể sẽ chấp nhận giá trị của bất kỳ loại dữ liệu dựng sẵn nào; . Đối số Biến thể sẽ không chấp nhận giá trị của loại do người dùng xác định. Tuy nhiên, hãy nhớ rằng danh sách, mảng, đối tượng và kiểu do người dùng xác định không thể và do đó không nên được chuyển theo giá trị

    Nếu đối số biến sau đó được sửa đổi bởi hàm hoặc phụ, thì biến có giá trị ban đầu sau khi hàm hoặc phụ trả về. Hàm hoặc phụ chỉ hoạt động trên bản sao đã truyền của biến, vì vậy bản thân biến đó không thay đổi

    Hai cách truyền đối số cho phương thức trong nhiều ngôn ngữ lập trình là truyền theo giá trị và truyền theo tham chiếu. Khi một đối số được truyền theo giá trị (mặc định trong C#), một bản sao giá trị của nó được tạo và truyền cho phương thức được gọi. Các thay đổi đối với bản sao không ảnh hưởng đến giá trị của biến ban đầu trong trình gọi. Điều này ngăn ngừa các tác dụng phụ ngẫu nhiên cản trở rất nhiều đến sự phát triển của các hệ thống phần mềm chính xác và đáng tin cậy. Mỗi đối số được truyền trong các chương trình cho đến nay đều được truyền theo giá trị. Khi một đối số được truyền theo tham chiếu, người gọi sẽ cung cấp cho phương thức khả năng truy cập và sửa đổi biến ban đầu của người gọi — không có bản sao nào được chuyển

    Để truyền một đối tượng bằng cách tham chiếu vào một phương thức, chỉ cần cung cấp dưới dạng đối số trong phương thức gọi biến tham chiếu đến đối tượng. Sau đó, trong phần thân phương thức, hãy tham chiếu đối tượng bằng tên tham số tương ứng. Tham số đề cập đến đối tượng ban đầu trong bộ nhớ, vì vậy phương thức được gọi có thể truy cập trực tiếp vào đối tượng ban đầu

    Trong phần trước, chúng ta đã bắt đầu thảo luận về sự khác biệt giữa các loại giá trị và loại tham chiếu. Một sự khác biệt lớn là

    • biến kiểu giá trị lưu trữ các giá trị, do đó, việc chỉ định một biến kiểu giá trị trong lệnh gọi phương thức sẽ chuyển một bản sao giá trị của biến đó sang phương thức, trong khi đó

    • Các biến kiểu tham chiếu lưu trữ các tham chiếu đến các đối tượng, do đó, việc chỉ định một biến kiểu tham chiếu làm đối số sẽ chuyển cho phương thức một bản sao của tham chiếu tham chiếu đến đối tượng

    Mặc dù bản thân tham chiếu được truyền theo giá trị, nhưng phương thức vẫn có thể sử dụng tham chiếu mà nó nhận được để tương tác với—và có thể sửa đổi—đối tượng ban đầu. Tương tự, khi trả về thông tin từ một phương thức thông qua câu lệnh return, phương thức này trả về một bản sao của giá trị được lưu trong biến kiểu giá trị hoặc một bản sao của tham chiếu được lưu trong biến kiểu tham chiếu. Khi một tham chiếu được trả về, phương thức gọi có thể sử dụng tham chiếu đó để tương tác với đối tượng được tham chiếu

    7. 18. 1 tham chiếu và tham số

    Điều gì sẽ xảy ra nếu bạn muốn truyền một biến theo tham chiếu để phương thức được gọi có thể sửa đổi giá trị của biến trong trình gọi?

    Tham số tham chiếu

    Áp dụng từ khóa ref cho một khai báo tham số cho phép bạn chuyển một biến cho một phương thức bằng cách tham chiếu—phương thức này sẽ có thể sửa đổi biến ban đầu trong trình gọi. Từ khóa ref được sử dụng cho các biến đã được khởi tạo trong phương thức gọi

    ra Thông số

    Trước một tham số với từ khóa out sẽ tạo một tham số đầu ra. Điều này cho trình biên dịch biết rằng đối số sẽ được truyền vào phương thức được gọi theo tham chiếu và phương thức được gọi sẽ gán một giá trị cho biến ban đầu trong trình gọi. Điều này cũng ngăn trình biên dịch tạo thông báo lỗi cho một biến chưa được khởi tạo được truyền dưới dạng đối số cho một phương thức

    Truyền các biến loại tham chiếu theo tham chiếu

    Bạn cũng có thể chuyển một biến kiểu tham chiếu theo tham chiếu, điều này cho phép bạn sửa đổi nó để nó tham chiếu đến một đối tượng mới. Chuyển tham chiếu theo tham chiếu là một kỹ thuật phức tạp nhưng hiệu quả mà chúng ta sẽ thảo luận trong Phần 8. 13

    7. 18. 2 Thể hiện Tham số ref, out và Giá trị

    Ứng dụng trong hình. 7. 19 sử dụng từ khóa ref và out để thao tác các giá trị số nguyên. Lớp chứa ba phương thức tính bình phương của một số nguyên

     1   // Fig. 7.19: ReferenceAndOutputParameters.cs
     2   // Reference, output and value parameters.
     3   using System;
     4
     5   class ReferenceAndOutputParameters
     6   {
     7      // call methods with reference, output and value parameters
     8      static void Main()
     9      {
    10         int y = 5; // initialize y to 5
    11         int z; // declares z, but does not initialize it
    12
    13         // display original values of y and z
    14         Console.WriteLine($"Original value of y: {y}");
    15         Console.WriteLine("Original value of z: uninitialized\n");
    16
    17         // pass y and z by reference
    18         SquareRef(ref y); // must use keyword ref
    19         SquareOut(out z); // must use keyword out
    20
    21         // display values of y and z after they're modified by
    22         // methods SquareRef and SquareOut, respectively
    23         Console.WriteLine($"Value of y after SquareRef: {y}");
    24         Console.WriteLine($"Value of z after SquareOut: {z}\n");
    25
    26         // pass y and z by value
    27         Square(y);
    28         Square(z);
    29
    30         // display values of y and z after they're passed to method Square
    31         // to demonstrate that arguments passed by value are not modified
    32         Console.WriteLine($"Value of y after Square: {y}");
    33         Console.WriteLine($"Value of z after Square: {z}");
    34      }
    35
    36      // uses reference parameter x to modify caller's variable
    37      static void SquareRef(ref int x)
    38      {
    39         x = x * x; // squares value of caller's variable
    40      }
    41
    42      // uses output parameter x to assign a value
    43      // to an uninitialized variable
    44      static void SquareOut(out int x)
    45      {
    46         x = 6; // assigns a value to caller's variable
    47         x = x * x; // squares value of caller's variable
    48      }
    49
    50      // parameter x receives a copy of the value passed as an argument,
    51      // so this method cannot modify the caller's variable
    52      static void Square(int x)
    53      {
    54         x = x * x;
    55      }
    56   }
    Original value of y: 5
    Original value of z: uninitialized
    
    Value of y after SquareRef: 25
    Value of z after SquareOut: 36
    
    Value of y after Square: 25
    Value of z after Square: 36

    Quả sung. 7. 19. Thông số tham chiếu, đầu ra và giá trị

    Phương thức SquareRef (dòng 37–40) tự nhân tham số x của nó và gán giá trị mới cho x. Tham số của SquareRef được khai báo là ref int, điều này cho biết rằng đối số được truyền cho phương thức này phải là một số nguyên được truyền theo tham chiếu. Bởi vì đối số được truyền bằng tham chiếu, phép gán ở dòng 39 sẽ sửa đổi giá trị của đối số ban đầu trong trình gọi

    Phương thức SquareOut (dòng 44–48) gán cho tham số của nó giá trị 6 (dòng 46), sau đó bình phương giá trị đó. Tham số của SquareOut được khai báo là out int, điều này cho biết rằng đối số được truyền cho phương thức này phải là một số nguyên được truyền theo tham chiếu và đối số đó không cần phải khởi tạo trước

    Phương thức Square (dòng 52–55) tự nhân tham số x của nó và gán giá trị mới cho x. Khi phương thức này được gọi, một bản sao của đối số được truyền cho tham số x. Do đó, mặc dù tham số x được sửa đổi trong phương thức, nhưng giá trị ban đầu trong hàm gọi không bị sửa đổi

    Phương thức Chính (dòng 8–34) gọi các phương thức SquareRef, SquareOut và Square. Chúng ta bắt đầu bằng cách khởi tạo biến y thành 5 và khai báo, nhưng không khởi tạo, biến z. Dòng 18–19 gọi phương thức SquareRef và SquareOut. Lưu ý rằng khi bạn chuyển một biến cho một phương thức có tham số tham chiếu, bạn phải đặt trước đối số bằng cùng một từ khóa (ref hoặc out) đã được sử dụng để khai báo tham số tham chiếu. Các dòng 23–24 hiển thị các giá trị của y và z sau các lệnh gọi tới SquareRef và SquareOut. Lưu ý rằng y đã được thay đổi thành 25 và z đã được đặt thành 36

    Dòng 27–28 gọi phương thức Square với y và z làm đối số. Trong trường hợp này, cả hai biến đều được truyền theo giá trị—chỉ các bản sao giá trị của chúng mới được truyền cho Square. Kết quả là giá trị của y và z lần lượt là 25 và 36. Các dòng 32–33 xuất các giá trị của y và z để cho thấy rằng chúng không bị sửa đổi

    Bạn có thể chuyển một đối tượng theo giá trị 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. “Truyền theo giá trị” có nghĩa là chuyển một bản sao của giá trị . "Truyền theo tham chiếu" đề cập đến việc chuyển tham chiếu thực của biến trong bộ nhớ.

    Các đối tượng có thể được truyền theo giá trị trong C++ không?

    Truyền theo giá trị . Đối tượng mới có bộ nhớ bổ sung được phân bổ cho nó và tất cả các giá trị cũng như đối tượng con được sao chép và lưu trữ riêng. When an object (or built-in type) is passed by value to a function, the underlying object is copied using its copy constructor. The new object has additional memory allocated to it and all values and sub-objects are copied and stored separately.

    C có vượt qua mọi thứ theo giá trị không?

    C luôn sử dụng 'truyền theo giá trị' để truyền đối số cho hàm (một thuật ngữ khác là 'gọi theo giá trị', có nghĩa giống như vậy), có nghĩa là mã trong một .

    Các đối tượng có được truyền theo giá trị trong C# không?

    Theo mặc định, C# không cho phép bạn chọn chuyển từng đối số theo giá trị hoặc theo tham chiếu. Các loại giá trị được truyền theo giá trị . Các đối tượng không được truyền cho các phương thức; .