2011-09-30 36 views
5

Có tương đương với từ khóa C# 'out' cho các tham số ngoài nhưng trong C++ không?Từ khóa 'out' trong C++

Tôi muốn có một hàm tạo cũng đặt một vài tham chiếu đến các biến mà nó được gọi.

+0

Bạn có muốn chỉ chú thích các tham số hàm của mình để cho biết giá trị sẽ thay đổi khi hàm trả về không? Hay bạn đang hỏi làm thế nào để gọi một hàm và chuyển tham số bằng tham chiếu (con trỏ) sao cho hàm có thể liên tục thay đổi giá trị mà người gọi đã chuyển vào? – selbie

+0

Bạn có ý gì khi "đặt một vài tham chiếu đến biến"? Điều này có lẽ không dịch từ C# sang C++ rất tốt. –

+0

bạn có thể có thể tự tạo một tính năng tương tự với một lớp mẫu có thể cho phép bạn viết các hàm như: void getValue (giá trị ); và làm cho nó ném nếu giá trị không được đặt trong hàm. – markh44

Trả lời

9

Không tương đương trực tiếp. Trong C++, bạn chọn giữa truyền theo giá trị, truyền giá trị con trỏ hoặc truyền tham số tham chiếu. Hai thứ hai có thể được sử dụng để lấy lại dữ liệu từ hàm.

VOID foo(int* pnA, int& nB) 
{ 
    *pnA = 1; 
    nB = 2; 
} 

int nA, nB; 
foo(&nA, nB); 
// nA == 1, nB == 2; 
+0

Damnit! Tôi cần phải nhanh hơn! +1 – Phil

+0

(Và bạn nên thích một tham chiếu đến một con trỏ, vì ngữ nghĩa là rõ ràng hơn: đối tượng phải tồn tại trước --i.e.bạn không thể vượt qua một con trỏ null) –

+0

Tôi cho rằng việc chuyển một tham chiếu trong C++ là * tương đương với C# 'out'. Cả hai thay đổi ngữ nghĩa từ giá trị gọi theo giá trị sang gọi theo tham chiếu. Cấp phiên bản C# chặt chẽ hơn về việc đảm bảo gán bên trong hàm ... chuyển một con trỏ, tuy nhiên, vẫn là giá trị gọi theo và có thể được mô phỏng trong C# với các đối tượng có thể thay đổi (hoặc 'không an toàn'). –

0

Bạn không cần từ khóa ngoài. Bạn sử dụng con trỏ.

int x = 47; 
f(&x); 
//x is 5 

void f(int* p) 
{ 
    *p = 5; 
} 

Xem những gì tôi đã làm ở đó? Bạn chuyển tham chiếu của x tới hàm để hàm thực sự viết một giá trị mới cho x.

+0

con trỏ không tương đương. với C# 's 'out', bạn _initialize_ tham số đó trong một số hàm. –

3

C# 's out có nghĩa là khởi tạo của một số giá trị được thực hiện trong một hàm. C++ không có giá trị tương đương.

Khởi tạo biến không phải thành viên là luôn luôn được thực hiện tại điểm khai báo và cho các biến thành viên được thực hiện trong hàm tạo, trước dấu ngoặc mở của hàm tạo.

May mắn thay, hiện đại, C++ biên dịch thực hiện RVO (Return Value Optimization), đúng đắn để const thường đi kèm với không có hiệu suất phạt:

const Foo foo = create_a_foo(); 

Một trình biên dịch tốt sẽ phát ra một cái gì đó giống như p-code sau:

BYTE foo_store [sizeof (Foo)]; 
create_a_foo (foo_store); 
const ALIAS Foo foo = foo_store; 

đâu ALIAS sẽ chỉ là một tên (đã nhập) khác cho foo_store, mà không có bất kỳ chi phí thời gian chạy nào. Việc cấp phát bộ nhớ cho foo_store thường là miễn phí, vì nó về cơ bản không có gì khác giống như một sự gia tăng khung stack.

Thậm chí nếu bạn vượt qua một tham chiếu đến một con trỏ,

void create_a_foo (Foo* &) {...} 

sau đó nó không phải là một tương đương. Mã này vẫn chống lại mã const-correct và bạn thực sự là chỉ định gán cho con trỏ, không giống như khởi tạo Foo.

Foo *p; // initialization of pointer is HERE, and nowhere else 
create_a_foo(p); // creates a Foo and _assigns_ it to po. 

Tài liệu tham khảo-to-con trỏ là lúc tốt nhất một hack nếu bạn có ý định một chính xác C# out clone, như thể ví dụ reference-to- boost::optional.