Tác dụng của Tham chiếu (reference) trong C++ là gì?

Đang học C++ qua clip youtube của forum DayNhayHoc. Em đã học tới bài Đa hình nhưng có 1 điều là cho dù nghĩ mãi em vẫn chưa thể hiểu tác dụng của reference để làm gì ngoài việc swap (hoán đổi). Nhưng thật sự chúng ta có thể swap mà ko cần reference mà :smile: Z reference để làm gì ?

1 Like

Mình nghĩ tác dụng của nó thể hiện khi truyền tham số vào hàm.
Nếu không dùng tham chiếu & thì máy sẽ phải tạo ra 1 vùng nhớ cho tham số hình thức( tốn bộ nhớ) rồi gán dữ liệu của tham số thực cho tham số hình thức(tốn thời gian), nhất là khí tham số thực là 1 đối tượng( có kích thước lớn)
Dùng tham chiếu & thì tham số hình thức và tham số thực sẽ dùng chung vùng nhớ nên sẽ tiết kiệm bộ nhớ và thời gian

3 Likes

Bạn thử đọc Giáo trình C++ của thầy Phạm Văn Ất đi

1 Like

Mình hiểu theo ví dụ tự nghĩ ra để nhớ.

  • Truyền giá trị: chụp ảnh con mèo và gửi ảnh nó cho bạn của bạn, bạn của bạn làm gì với con mè trong ảnh thì con mèo của bạn vẫn nguyên vẹn. Mất công chụp và gửi ảnh
  • Reference: Bạn đưa luôn con mè ấy cho bạn của bạn, bạn của bạn cắt râu của nó rồi trả lại bạn con mèo, con mèo của bạn có bộ râu bị thay đổi.
8 Likes

tác dụng y như con trỏ nhưng ko có NULL. Khi truyền con trỏ khi deref thì phải coi chừng NULL pointer. Truyền tham chiếu thì ko có vụ con trỏ NULL này.

1 Like

ví dụ thực tế quá ha

1 Like

Tham chiếu thừa hưởng khả năng của con trỏ, nhưng cú pháp của nó dễ sử dụng hơn nhiều so với con trỏ. Tham số truyền vào hàm bằng tham chiếu sẽ không bị lộ những chi tiết cài đặt trong hàm.
=>Nó là một công cụ tốt để cài đặt các hàm toán tử thay vì dùng con trỏ…

2 Likes

cụ thể là trên kiến trúc 32 bit, thì 1 địa chỉ tốn 4byte, ví dụ 1 struct có nội dung như sau

typedef struct
{
    int namsinh;
    int sodienthoai;
} thongtin;
thongtin ham1(thongtin sv1);
thongtin ham2(const thongtin &sv2);

thì ở ham2 bộ nhớ tốn sử dụng khi thực hiện hàm chỉ là 4byte
còn hàm 1 thì tốn 8byte = 4byte int năm sinh + 4byte int số điện thoại
nếu struct có thêm các trường

name[50];
float;
int;
int;
int;

thì bộ nhớ cần khi hàm sử dụng là các giá trị bộ nhớ của các kiểu dữ liệu công lại
còn với cách dùng tham chiếu & thì chỉ tốn 4byte với kiến trúc x86
& dùng được cho cả hàm dùng được cho cả biến, khi dùng nên cân nhắc có nên sử dụng const không/

3 Likes

tác dụng lớn nhất khi dùng biến tham chiếu, hàm tham chiếu, hằng tham chiếu là tiết kiện bộ nhớ, và thời gian, dễ dàng thay đổi giá trị của biến, cái này có nói trong sách của thầy ất, nhưng hình như có chỗ sai, không đúng trong mọi trường hợp, vì khi thử trên ví dụ thực tế và quan sát thì thấy k đúng với câu " hàm sử dụng tham chiếu & nhanh hơn hàm không sử dụng)

1 Like

Tất nhiên là nhanh hơn. Có thể chỉ là 0.01 milisecond nên bạn k nhìn thấy. Khi khởi tạo hàm, hệ thống sẽ tốn thời gian để xử lý việc copy tham số. Còn với ref thì nó tham chiếu làm việc trực tiếp với vùng nhớ.

Thank bạn vì đã nói rõ về bộ nhớ, cái này mình cũng biết, ở trên mình chỉ muốn nêu ví dụ sự khác nhau của 2 cách đó :smile:

2 Likes

nhanh hơn nhưng chỉ trong 1 số trường hợp, mình đã từng thấy 1 số ví dụ chỉ ra rằng hàm không sử dụng tham chiếu & vẫn nhanh hơn hàm có sử dụng, deasembly

Tham chiếu và con trỏ

  • tham chiếu không thể thay đổi đối tượng, con trỏ có thể
  • tham chiếu không trỏ đến null giống con trỏ.
  • con trỏ linh hoạt hơn

Tham chiếu và Không tham chiếu

  • tham chiếu sẽ nhanh hơn với đối tượng phức tạp khi đưa vào hàm.
  • có thể thay đổi giá trị khi ra khỏi hàm
1 Like

Là gì nhỉ? Khái niệm này mới quá.

Xin hãy chỉ ra trường hợp mà bạn cho là ngoại lệ.

trước trên cộng đồng c việt có 1 topic rồi bạn

#include <iostream>
#include <windows.h>
#include <limits.h>
#include <iomanip>
#include <ctime>
using namespace std;
int n=327680;
long *A=NULL;
 
//Đo thử thời gian của 2 Neg(x) với ~x+1 xem cái nào nhanh hơn nè
int Neg(const int & x)
{
    return -x;
}
 
int Neg2(int x)
{
    return -x;
}
 
int main()
{
    //Tạo ra mảng có 1 tỷ phần tử nhẫu nhiên
    srand(time(NULL));
    A=(long*)malloc(sizeof(long)*n);
    for (int i=0;i<n;i++)
        A[i]=rand();
 
    LARGE_INTEGER lFreq,lStart,lEnd;
    QueryPerformanceFrequency(&lFreq);
   
    //Đo điểm cho Neg
    QueryPerformanceCounter(&lStart);
    for (int i=0;i<n;i++)
        Neg(A[i]);
    QueryPerformanceCounter(&lEnd);
    cout<<"Time Neg () take : "<<setprecision(20)<<long double(lEnd.QuadPart-lStart.QuadPart)/lFreq.QuadPart<<endl;
 
    //Đo điểm cho hàm còn lại Neg2
    QueryPerformanceCounter(&lStart);
        for (int i=0;i<n;i++)
            Neg2(A[i]);
    QueryPerformanceCounter(&lEnd);
    cout<<"Time Neg2() take : "<<setprecision(20)<<long double(lEnd.QuadPart-lStart.QuadPart)/lFreq.QuadPart<<endl;
    system("pause");
}

Kiến thức nông cạn nên mình vẫn chưa thấy chổ nào nhanh hết.

1 Like

theo mình nghĩ thế này: với những kiểu dữ liệu cơ bản int, char, … thì truyền tham chiếu sẽ truyền vào địa chỉ nên là 32 hoặc 64 bit nhiều hơn kiểu dữ liệu cơ bản đó. Do đó nó có thể chạy chậm hơn.

Tham chiếu được dùng trong các hàm khi bạn muốn thay đổi giá trị khi truyền các biến vào. Như các hàm int hay khác trừ void thì nó thường trả về 1 dữ liệu nào đó, nhưng ở hàm đó, bạn muốn nó trả về 2 kiểu giá trị thì bạn phải dùng tham chiếu. Như hàm swap thì bạn phải dùng tham chiếu nếu không thì nó vẫn sẽ như cũ, cái này bạn có thể tìm hiểu thêm “Con Trỏ”, bạn có thể tìm sách “Head First C Book by Andrew Stellman”

2 Likes

Câu hỏi rất hay! Thử tưởng tượng khi có 2 lập trình viên cùng làm việc với 1 biến, 1 người phụ trách phần khai báo còn người kia thì sử dụng. Người sau chỉ đơn giản cần 1 cách để tiếp cận biến đó và 1 tham chiếu là nhiều hơn cả đủ.

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?