2011-10-24 17 views
8

Trình lập trình công bằng mới ở đây và lời xin lỗi trước cho các câu hỏi ngớ ngẩn.Biến là chỉ đọc sau khi gán vào thời gian chạy?

Tôi có biến số int trong một chương trình mà tôi sử dụng để xác định độ dài mảng của tôi nên ở trong một số cấu trúc của tôi. Tôi đã sử dụng để đặt nó trong tiêu đề của tôi như là một const int. Bây giờ, tôi muốn nĩa chương trình của tôi để cung cấp cho các biến giá trị khác nhau tùy thuộc vào các đối số được đưa ra trong, nhưng giữ nó chỉ đọc sau khi tôi gán nó vào thời gian chạy.

Một vài ý tưởng tôi đã phải làm điều này. Có cách nào ưu tiên không?

  1. Khai báo một const int * trong tiêu đề của tôi và gán nó vào const int trong chức năng chính của tôi, nhưng điều đó có vẻ khó khăn.
  2. Biến nó thành một đồng bằng int trong chức năng chính của tôi.
  3. Chuyển biến làm đối số khi hàm được gọi.
  4. Điều gì đó khác mà tôi chưa từng nghĩ đến.
+0

Nếu bạn định sử dụng biến này để tạo các mảng có kích thước biến tại thời gian chạy, thì đây không phải là chuẩn C++. Tiêu chuẩn C++ không cho phép ** Các mảng độ dài thay đổi (VLA) **. Vì vậy, độ dài của mảng phải là một hằng số thời gian biên dịch. –

+0

@Als: Tôi đang tạo các mảng có độ dài không đổi, nhưng tôi không chắc chắn chiều dài là bao lâu cho đến khi chạy. –

+1

@BlueMagister: Sau đó, chúng không liên tục. "hằng" trong ngữ cảnh này có nghĩa là "hằng số biên dịch-thời gian". Bạn không thể đưa ra một mảng (trừ khi bạn phân bổ nó bằng 'mới') một kích thước không biên dịch trong C++.Bạn phải sử dụng 'std :: vector' hoặc phân bổ nó bằng' new'. –

Trả lời

9

Tôi muốn sử dụng biến chức năng tĩnh và hàm đơn giản. Quan sát:

int GetConstValue(int initialValue = 0) 
{ 
    static int theValue = initialValue; 
    return theValue; 
} 

Vì đây là biến tĩnh cấp chức năng, nó chỉ được khởi tạo lần đầu tiên. Vì vậy, tham số initialValue là vô ích sau lần chạy đầu tiên của hàm. Vì vậy, tất cả những gì bạn cần làm là đảm bảo rằng cuộc gọi đầu tiên của hàm là một hàm khởi tạo nó.

0

Tôi rất muốn nói rằng những gì bạn muốn không có ý nghĩa. Một hằng số là một cái gì đó mà không thay đổi giá trị của nó, không phải cái gì đó có thể thay đổi giá trị của nó một lần hoặc hai lần. Nếu bạn muốn biến toàn cầu, chỉ cần biến nó thành không đổi.

Mặt khác, nếu bạn có giá trị không đổi phạm vi, bạn chỉ cần khai báo và khởi tạo chúng cùng một lúc, theo hướng dẫn chung C++ để khai báo gần với trang sử dụng nhất có thể. Ví dụ, đánh dấu việc sử dụng các hằng số trong phạm vi địa phương sau:

for (auto it = v.begin(), end = v.end(); it != end; ++it) 
{ 
    const Foo & x = *it; 
    const std::size_t n = x.get_number_of_bars(); 

    // use x and n ... 

    const bool res = gobble(x, zip(n)); 
    if (res && shmargle(x)) { return 8; } 
} 

Dưới đây trình biên dịch thậm chí có thể chọn không tạo ra bất kỳ mã đặc biệt cho các biến ở tất cả nếu giá trị của họ đã được biết đến thông qua các phương tiện khác.

+1

Tôi đang tìm cách gán một biến một lần vào thời gian chạy, nhưng sau đó biến nó thành bất biến sau đó. –

1

Khi nào bạn biết chính xác giá trị? Nếu bạn đọc nó từ một tập tin hoặc bất cứ điều gì, bạn chỉ có thể nói:

const int n = determine_correct_value(); 
+0

Tôi biết giá trị chính xác từ các đối số được truyền vào. Nhưng cấu trúc này có ý nghĩa. Tôi sẽ fiddle với mã của tôi và xem nếu điều này hoạt động. –

+2

Bạn có nghĩa là 'argv'? Nó sẽ không hoạt động sau đó, xin lỗi. Globals được khởi tạo trước khi luồng điều khiển vào 'main'. – fredoverflow

6

C++ không có một giải pháp tích hợp cho điều này, nhưng nếu bạn thực sự muốn chắc chắn rằng int của bạn chỉ được giao một lần , bạn có thể tạo lớp int đặc biệt của riêng mình:

class MyConstInt 
{ 
public: 
    MyConstInt(): assigned(false) {} 
    MyConstInt& operator=(int v) 
    { 
     assert(!assigned); 
     value = v; 
     assigned = true; 
     return *this; 
    } 
    operator int() const 
    { 
     assert(assigned); 
     return value; 
    } 
private: 
    int value; 
    bool assigned; 
}; 


MyConstInt mi; 
// int i = mi;   // assertion failure; mi has no value yet 
mi = 42; 
// mi = 43;  // assertion failure; mi already has a value 
int* array = new int[mi]; 
+0

Thay vì 'MyConstInt', tôi sẽ biến nó thành' MySettings', nhưng khái niệm tương tự. Ngoài ra, có thể xây dựng từ một giá trị sẽ là một ý tưởng _great_. –

+0

@Mooing Duck: Đúng, nhưng tôi muốn thể hiện việc triển khai đơn giản nhất có thể (ví dụ: tạo mẫu nó trên loại giá trị có lẽ cũng là một ý tưởng hay). – imre

+0

Tôi nghĩ rằng đó là ý tưởng tuyệt vời quá. Tốt hơn hàm có 'tĩnh'. Cảm ơn! –

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