2009-08-25 21 views
8

Trong VC++ khi tôi cần phải xác định một mảng ràng buộc cho một biến thành viên lớp tôi làm điều đó theo cách này:Làm tất cả các trình biên dịch C++ cho phép sử dụng biến thành viên lớp int const tĩnh như một mảng bị ràng buộc?

class Class { 

private: 
    static const int numberOfColors = 16; 
    COLORREF colors[numberOfColors]; 
}; 

(xin vui lòng đừng nói với tôi về việc sử dụng std :: vector đây)

này cách tôi có một hằng số có thể được sử dụng như một mảng bị ràng buộc và sau đó trong mã lớp để xác định ràng buộc vòng lặp câu lệnh và đồng thời nó không hiển thị ở bất kỳ nơi nào khác.

Câu hỏi đặt ra là liệu việc sử dụng static const int biến thành viên này chỉ được phép của VC++ hay nó được cho phép bởi các trình biên dịch phổ biến khác?

+8

"xin vui lòng không cho tôi biết về cách sử dụng std :: vector here" - không, điều đó sẽ không phù hợp. Bạn nên sử dụng 'std :: tr1 :: array'. ':)' – sbi

Trả lời

4

Vâng, đó là 100% hợp pháp và cần được cầm tay. Tiêu chuẩn C++ nói điều này trong 5.19 - Biểu thức liên tục "(nhấn mạnh của tôi):

Ở một vài nơi, C++ yêu cầu biểu thức đánh giá một hằng số tích phân hoặc liệt kê: như giới hạn mảng (8.3.4, 5.3.4) , như trường hợp biểu thức (6.4.2), là độ dài trường bit (9.6), làm khởi tạo bảng liệt kê (7.2), làm khởi tạo thành viên tĩnh (9.4.2), và là đối số mẫu không kiểu hoặc liệt kê (14.3) .

constant-expression: 
    conditional-expression 

Một liên tục thể hiện không thể thiếu có thể liên quan đến chỉ literals (2.13), điều tra viên, biến const hay các thành viên dữ liệu tĩnh của không tách rời hoặc loại liệt kê khởi tạo với biểu thức hằng số (8.5), các tham số mẫu không kiểu của các kiểu tách rời hoặc kiểu liệt kê và biểu thức sizeof.

Điều đó có vẻ như VC6 không hỗ trợ. Xem StackedCrooked's answer để biết cách giải quyết tốt. Trên thực tế, tôi thường thích các đề cập đến StackedCrooked phương thức enum cho loại điều này.

Là một FYI, kỹ thuật "static const" hoạt động trong VC9, GCC 3.4.5 (MinGW), Comeau và Mars kỹ thuật số.

Và đừng quên rằng nếu bạn sử dụng thành viên "` const tĩnh ", bạn sẽ need a definition for it in addition to the declaration nói đúng. Tuy nhiên, hầu như tất cả các trình biên dịch sẽ cho phép bạn thoát khỏi việc bỏ qua định nghĩa trong trường hợp này.

1

Tôi đã ngừng làm phiền về tính di động của những năm trước đó. Có lẽ vẫn có các trình biên dịch không hỗ trợ nó, nhưng gần đây tôi chưa gặp bất kỳ ai trong số đó.

13

Hành vi đó là hợp lệ theo tiêu chuẩn C++. Bất kỳ trình biên dịch nào gần đây nên hỗ trợ nó.

6

Đây là tiêu chuẩn C++ trong hơn một thập kỷ nay. Nó thậm chí còn được VC hỗ trợ - bạn còn muốn gì hơn nữa? (@Neil: Còn SunCC thì sao? :^>)

6

Tôi tin rằng Visual Studio 2005 và hơn thế nữa hỗ trợ nó. Trình biên dịch XCode C++ cũng (thực tế là gcc).

Nếu bạn muốn an toàn, bạn luôn có thể sử dụng hack enum cũ mà tôi đã học được từ Hiệu quả C++. Nó giống như thế này:

class Class { 

private: 
    enum { 
     numberOfColors = 16 
    }; 
    COLORREF colors[numberOfColors]; 
}; 

Hy vọng điều này sẽ hữu ích.

+0

Ngay cả VS 2k3 cũng hỗ trợ nó. – sharptooth

+0

Enum 'hack' không cần thiết nếu bạn đang xử lý mã C++, nhưng nếu bạn muốn khai báo hoạt động trong C hoặc trong VC++ 6, thì điều này tốt hơn phương pháp phổ biến hơn khi sử dụng #define trong quan điểm của tôi. –

2

Tôi khá chắc chắn rằng điều này cũng sẽ hoạt động với gcc và Solaris, nhưng tôi không thể xác minh điều này tại thời điểm này.

Trong tương lai, bạn có thể mở rộng ý tưởng như thế này:

template<int size> 
class Class { 
private: 
    COLORREF colors[size]; 
}; 

và sử dụng nó như thế này:

Class<5> c; 

để bạn không bị giới hạn chính xác một kích thước bộ đệm trong ứng dụng của bạn.

+0

Bạn đang sử dụng số ma thuật, đó là câu hỏi mà bạn đang cố tránh. –

+0

@Neil: Tuy nhiên, số ma thuật 5 ở trên có thể được thay thế bằng 'int const int' từ một lớp 'c' có thể tự tìm thấy thành viên. – quamrana

-1

Có thể trả lời các câu hỏi như thế này bằng cách tham khảo quá trình speicifcation ISO C++ nhưng thông số kỹ thuật khó cho mọi người khó đọc hơn. Tôi cho rằng câu trả lời đơn giản nhất là bản lề trên hai điều:

  • Microsoft Visual Studio 2005 trở lên là một triển khai C++ tương đối phù hợp. Nếu nó cho phép bạn làm điều gì đó, rất có thể là tiêu chuẩn của nó.
  • Tải xuống nội dung nào đó như Mã :: Khối để tải trình biên dịch GCC để thử nội dung. Nếu nó hoạt động trong MS và GCC, rất có thể là, tiêu chuẩn của nó.
+0

Thông số kỹ thuật rất dễ nhận (với $ 30): http://stackoverflow.com/questions/81656/where-do-i-find-the-current-x-standard/83763#83763 Đọc thông số kỹ thuật là khác nhau câu chuyện, nhưng các nhà lập trình C++ nghiêm túc có lẽ vẫn nên tham khảo nó theo thời gian: http://stackoverflow.com/questions/1123455/should-every-c-programmer-read-the-iso-standard-to-become-professional –

13

Đây là trình biên dịch hợp lý hiện đại hợp lệ cho C++ và hầu hết (tất cả?) Đều hỗ trợ nó.Nếu bạn đang sử dụng tăng, bạn có thể nhận được hỗ trợ di động cho tính năng này trong các hình thức BOOST_STATIC_CONSTANT vĩ mô:

class Class { 
private: 
    BOOST_STATIC_CONSTANT(int, numberOfColors = 16); 
    COLORREF colors[numberOfColors]; 
}; 

Các vĩ mô được mở rộng để static const int numberOfColors = 16 nếu trình biên dịch hỗ trợ này, nếu không nó phải viện đến enum { numberOfColors=16 };.

3

Bên cạnh câu trả lời khác bạn có thể sử dụng chức năng sau đây xác định số phần tử trong mảng tĩnh alocated:

template<typename T, size_t length> 
size_t arrayLength(T (&a)[length]) 
{ 
    return length; 
} 
Các vấn đề liên quan