2013-06-18 84 views
7

Cho đến nay tôi biết rằng nếu bạn muốn vượt qua một giá trị mặc định cho một cuộc tranh cãi với một chức năng đó là một đối tượng, bạn làm điều đó như thế này:giá trị đối tượng mặc định trong chức năng với đối số mặc định giá trị

void function(MyObject obj = MyObject()){ 
    ... 
} 

Tuy nhiên , Tôi đã đi xung quanh với một số cú pháp thú vị gần đây, mà confuses tôi. Điều gì sẽ xảy ra khi chúng ta gọi hàm như thế này?

void function(MyObject obj = 0){ 
    ... 
} 

Lưu ý, chúng tôi đang truyền một đối tượng chứ không phải con trỏ. Đoạn mã trên biên dịch tốt, không có lỗi hoặc cảnh báo. Và điều này luôn luôn kêu gọi các nhà xây dựng với một đối số - MyObject được định nghĩa như thế này:

class MyObject{ 
public: 
    MyObject(double n){std::cout << "Argumented\n";} 
    MyObject(){std::cout << "Default\n";} 
}; 

Ngoài ra, nơi được hành vi này ghi nhận (vì tôi đã tìm kiếm và không thể tìm thấy nó)?

+1

Chương C++ tiêu chuẩn 4 (Chuyển đổi chuẩn) và chương 12.3 (Các chức năng thành viên đặc biệt/Chuyển đổi). Và cũng có 13.3.3.1 (chuỗi covnersion ngầm). – jrok

+0

@jrok Cảm ơn rất nhiều. –

+0

Bạn được chào đón. Các số chương là từ dự thảo n3337 nhưng tôi mong đợi chúng sẽ giống nhau trong tiêu chuẩn chính thức (C++ 11). – jrok

Trả lời

11

Tham số mặc định là MyObject được xây dựng ngầm từ 0, bằng cách gọi hàm tạo MyObject(double). constructor này cho phép bạn nhanh chóng ngầm MyObjects như thế này:

MyObject o1 = 0; 
MyObject o2 = 420/10.; 

Nếu hành vi này không có ý định, sau đó làm cho các nhà xây dựng explicit. Điều này cũng sẽ đòi hỏi một sự thay đổi thông số function 's mặc định:

explicit MyObject(double n); 

void function(MyObject obj = MyObject(0)); 
+1

Ngoài ra nếu bạn muốn vô hiệu hóa hành vi này, bạn có thể đánh dấu hàm tạo của bạn là 'rõ ràng ' – WaelJ

+0

Ồ đúng ... Tại sao tôi không nghĩ về điều đó trước đây? Cảm ơn. –

5

MyObject như có một cái gọi là implicit converting constructor từ kép. Như 0 là okay cho gấp đôi, hiệu ứng bạn thấy giống như bạn đã làm MyObject (0.0).

4

Với điều kiện là biểu thức sau đây:

MyObject obj = 0; 

biên dịch và có một giá trị kiểu MyObject, sau đó một cuộc gọi chức năng tham gia một MyObject sẽ có thể làm việc trong cùng một cách.

Hãy tưởng tượng chức năng này chữ ký:

void function(MyObject obj){ 
    ... 
} 

Và mã gọi sau đây:

MyObject obj = 0; 
function(obj); 

này tương đương với mã này gọi thứ hai:

function(MyObject obj = 0); 

Bởi vì giá trị của MyObject obj = 0; bằng MyObject đã được xây dựng ed trong dòng mã đó.

Bạn chỉ cần tiến một bước và cung cấp giá trị tham số mặc định bằng cách tận dụng cùng một quy tắc.

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