2009-12-02 43 views
6

Tôi muốn chuyển một con trỏ bằng tham chiếu đến hàm, sao cho tôi có thể thay đổi địa chỉ con trỏ được chuyển đến và tôi muốn gán đối số này làm mặc định giá trị.Con trỏ qua C++ bằng cách tham chiếu và gán giá trị mặc định

một cái gì đó như thế này:

trong tờ khai

void myFunc(SomeType* &var=NULL); 

và định nghĩa:

void MyClass::myFunc(SomeType* &var){ 
    if(var!=NULL) 
     (*var)=(*someOtherPointer); 

    if(someCondition) 
     var=NULL; 
} 

như vậy mà một callee có thể quyết định xem anh ấy muốn gọi hàm với một đối số hoặc không tranh cãi. Và sucht rằng nếu ông quyết định để vượt qua một cuộc tranh cãi, và someCondition giữ, con trỏ qua sẽ trỏ đến NULL sau đó

tuy nhiên - nếu tôi cố gắng để làm điều đó như thế này tôi nhận được một:

Lỗi C2440: 'mặc định đối số ':' int 'không thể được chuyển thành' SomeType * & '

Cảm ơn sự trợ giúp!

Trả lời

7

Thông báo lỗi cho biết tất cả: bạn đang chuyển một số nguyên thay vì tham chiếu đến một con trỏ đến một số loại. Để làm những gì bạn muốn, bạn có thể sử dụng một con trỏ-to-một-con trỏ-to-SomeType:

void myFunc(SomeType** var=NULL); 

void MyClass::myFunc(SomeType** var){ 
    if(var!=NULL && *var!=NULL) 
     (**var)=(*someOtherPointer); 

    if(var!=NULL && someCondition) 
     *var=NULL; 
} 
+0

Trừ khi "someCondition" bao gồm "var! = NULL", bạn vừa chấp nhận câu trả lời mà không tham chiếu đến con trỏ NULL. Có lẽ không phải những gì bạn muốn. – imaginaryboy

+0

Ngoài ra, hãy lưu ý rằng việc sử dụng (** var) = (* someOtherPointer) sẽ thực sự tạo một bản sao đối tượng. Nếu bạn chỉ có nghĩa là để làm một bản sao con trỏ, bạn có thể muốn (* var) = (someOtherPointer). – Thought

14

NULL không phải là một giá trị - không thể chuyển qua tham chiếu. Nó sẽ giống như truyền 4 đến một hàm mong đợi một int&.

Phần 'int' là vì NULL là một macro được xác định 0.

Đặt cược tốt nhất của bạn sẽ sử dụng con trỏ để chuyển con trỏ bằng tham chiếu, tức là con trỏ kép. Sau đó, nếu tham số là NULL, không có gì được thông qua. Nếu không, đó là địa chỉ của con trỏ cần được sửa đổi [để trỏ tới NULL nếu someCondition giữ].

+0

+1 Bạn đã nhận được ngay một cách nhanh chóng;) – AraK

+0

mất ngủ bị đe dọa. – aib

+1

Một tùy chọn khác sẽ sử dụng tăng :: tùy chọn (không có ý định chơi chữ) –

2

Bạn cũng có thể xem xét sử dụng tăng :: tùy chọn (không mã đơn giản nhất bạn có thể sử dụng, nhưng tùy chọn là có):

void f(boost::optional<int&> r = boost::optional<int&>()) 
{ 
    if (r) *r = 5; 
} 
int main() 
{ 
    int x = 0; 
    f(x); std::cout << x << std::endl; // 5, it did change the value 
    f(); // compiler will default to an empty optional<int&> object 
} 
+0

+1 cho ví dụ. –

2

Ok, tôi có thể hiểu tại sao bạn làm điều này từ góc độ thực hiện bộ não C++, nhưng bạn có thực sự làm điều đó trong mã sản xuất không? Nó trông giống như một kỹ thuật cực kỳ mù mờ với các tác dụng phụ, khi nhìn vào mã như một đồng nghiệp 1 năm sau đó. Bạn có nghĩ đến việc sử dụng hai hàm riêng biệt với các tên rõ ràng, một hàm trả về một con trỏ và một cái làm bất kỳ công việc cần thiết nào khác không?

2

Tại sao không chỉ quá tải chức năng?

void myFunc() { 
    //whatever logic should happen if a null pointer is passed in 
} 

void myFunc(SomeType* &var) { 
    if(var!=NULL) { 
    (*var)=(*someOtherPointer); 
    } 

    if(someCondition) { 
     var=NULL; 
    } 
} 
Các vấn đề liên quan