2013-06-10 41 views
5

Tôi có đoạn code:Quá tải trên const và dễ bay hơi - tại sao nó hoạt động theo tham chiếu?

#include "stdafx.h" 
#include <iostream> 

using namespace std; 


void func(const int& a) 
{ 
    std::cout << "func(const)" << std::endl; 
} 

void func(volatile int& a) 
{ 
    std::cout << "func(volatile)" << std::endl; 
} 

void func(const volatile int& a) 
{ 
    std::cout << "func(const volatile)" << std::endl; 
} 

int main() 
{ 
    const int a = 0; 
    const volatile int b = 0; 
    volatile int c = 0; 
    func(a); 
    func(b); 
    func(c); 
    system("pause"); 
    return 0; 
} 

Đoạn mã trên cho thấy quá tải dựa trên việc các thông số là const/dễ bay hơi. Tuy nhiên, nếu tôi thay đổi thông số từ int& thành int, mã không còn biên dịch và tôi không thể quá tải dựa trên các loại tham số const/volatile. Tôi không nhận được lý do tại sao chúng tôi có thể quá tải dựa trên const và dễ bay hơi nếu int được thông qua tham chiếu, nhưng không nếu nó được thông qua bởi giá trị?

EDIT Tôi nên nhấn mạnh Tôi hiểu tham chiếu là gì - Tôi không hiểu tại sao bí danh tham chiếu được phép quá tải trên const nhưng int bình thường thì không.

Trả lời

4

Có lẽ sẽ hữu ích nếu bạn lùi lại một bước so với các chức năng và chỉ xem xét các trường hợp sử dụng.

tiên, chúng ta sẽ xác định một số nguyên và một số nguyên liên tục để sử dụng trong ví dụ của chúng tôi:

int  anInt  = 1; 
const int aConstInt = 1; 

Tiếp theo, chúng ta hãy nhìn vào những gì xảy ra khi sử dụng các biến này để thiết lập các giá trị của số nguyên khác và liên tục số nguyên:

int  a = anInt;  // This works, we can set an int's value 
         // using an int 
int  b = aConstInt; // This works, we can set an int's value 
         // using a const int 
const int c = anInt;  // This works, we can set a const int's value 
         // using an int 
const int d = aConstInt; // This works, we can set a const int's value 
         // using a const int 

Như bạn có thể thấy, không có cách nào để giải quyết mà quá tải của một hàm để chọn dựa trên hành vi (một int const có thể được chấp nhận bởi cả một int và int const, và tương tự một int có thể được chấp nhận bởi cả int và int int).

Tiếp theo, chúng ta sẽ có một cái nhìn vào những gì sẽ xảy ra khi vượt qua tập đầu tiên của biến để tham khảo:

int& a = anInt;  // This works because we are using a 
        // non-constant reference to access a 
        // non-constant variable. 
int& b = aConstInt; // This will NOT work because we are 
        // trying to access a constant 
        // variable through a non-constant 
        // reference (i.e. we could 
        // potentially change a constant 
        // variable through the non-const 
        // reference). 

const int& c = anInt;  // This works because we are using a 
          // constant reference (i.e. "I cannot 
          // try to change the referenced 
          // variable using this reference") to 
          // a non-constant variable. 
const int& d = aConstInt; // This will work because we are trying 
          // to access a constant variable 
          // through a constant reference. 

Như bạn thấy, có một số hành vi hữu ích mà có thể đã ra khỏi phân biệt giữa một tham chiếu int và tham chiếu int const (nghĩa là không cho phép tạo tham chiếu không liên tục khi một kiểu tham chiếu không đổi được mong đợi).

13

Vấn đề là cấp cao nhất const và/hoặc volatile bị bỏ qua ở độ phân giải quá tải. Vì vậy,

void foo(const int); 

là chính xác giống như

void foo(int); 

và tương tự cho volatile. Đây là một quy tắc ngôn ngữ, và nó có ý nghĩa vì các đối số được truyền theo giá trị. Mặt khác, tham chiếu đến const/volatile hoặc con trỏ đến const/volatile có nghĩa khác: bạn không được phép gọi các phương thức không const/dễ bay hơi về những gì chúng đề cập đến hoặc trỏ đến. Ở đây, constvolatile không phải là cấp cao nhất.

void foo(int& i);  // can modify what i refers to, and this has effects outside of foo. 
void foo(const int& i); // cannot modify what i refers to 

Hai tuyên bố ở trên có ngữ nghĩa rất khác nhau, do đó ngôn ngữ làm cho chúng khác biệt liên quan đến độ phân giải quá tải.

+0

Bạn có thể giải thích về sự khác biệt giữa int và int- Tôi cho rằng tham chiếu chỉ là bí danh cho một biến khác không? Vì vậy, int & và int không khác nhau? Một chỉ có nghĩa là bí danh? – user997112

+1

@ user997112 Khi bạn sử dụng tài liệu tham khảo, không có bản sao nào được thực hiện. Khi bạn sử dụng giá trị truyền theo giá trị đơn giản, đối số sẽ được sao chép. –

+0

@ user997112 Tôi đã cố gắng xây dựng.Trong trường hợp tham chiếu, ngữ nghĩa hoàn toàn khác nhau. Nó rất hữu ích cho ngôn ngữ có quá tải riêng biệt. Không có chúng sẽ gây nhầm lẫn. – juanchopanza

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