2012-02-10 22 views
5

Đầu tiên, tôi thực sự không gặp vấn đề gì, nhưng tôi muốn giữ mọi thứ càng đơn giản càng tốt. Tôi đang sử dụng một lớp templated tên là Math và bên cạnh rất nhiều công cụ khác có chức năng ngẫu nhiên.Chức năng tĩnh không có khuôn mẫu trong lớp templated

Các loại hàm ngẫu nhiên khác nhau và một hàm để đặt hạt giống ngẫu nhiên. Vì vậy, mọi chức năng ngoại trừ chức năng hạt giống sử dụng loại class Real. Nhưng khi tôi muốn thiết lập các hạt giống tôi phải vượt qua một số ngẫu nhiên (haha) gõ để có thể gọi hàm:

Math<u32>::SeedRandom(System::time()); 

Một lần nữa đây không phải là một vấn đề thực sự, nhưng tôi tò mò nếu nó có thể nhận được kết quả tương tự mà không cần sử dụng <u32>.

Dưới đây là một đoạn trích từ lớp Math:

template <class Real> 
class Math 
{ 
public: 
    static void SeedRandom(u32 seed) { srand(seed); } 
    static Real UnitRandom() { return (Real)((f64)rand()/(f64)RAND_MAX); } 
}; 

btw. f64 được nhập vào doubleu32 đến unsigned int.

Trả lời

4

Chức năng tĩnh phải được gọi bằng ClassName::FunctionName. Vì ClassName là mẫu, bạn phải chỉ định đối số mẫu. Các hàm tĩnh cũng có thể được gọi trên một đối tượng, tức là object.StaticFunctionName, vì vậy nếu bạn đã có đối tượng, bạn có thể tránh chỉ định đối số mẫu, nhưng theo ý kiến ​​cá nhân của tôi gọi hàm tĩnh trên đối tượng là xấu.

Tôi sẽ làm gì nếu tôi là bạn làm cho chức năng trở thành một người không phải là người bạn (bạn bè với mẫu, nếu cần), trong cùng một không gian tên như lớp của bạn.

+0

Vâng, một đối tượng đơn lẻ để gọi chức năng đó sẽ là có thể, nhưng trong trường hợp đó nó sẽ thực sự xấu xí :) Chỉ muốn biết nếu có cách để mã hóa nó, do đó không cần phải xác định loại. Tôi đã thử một chút và có thể gọi nó như thế này 'Math :: SeedRandom ((u32) System :: time()); '. Điều này ít nhất sẽ hiển thị, rằng loại không được sử dụng, nhưng nó chỉ làm cho thời gian biên dịch không cần thiết lâu hơn, và nó thậm chí còn xấu xí hơn sau đó chỉ cần gọi với ''. – v01pe

+0

@ v01pe: sử dụng 'void *' trong ý kiến ​​sai lệch thiên vị của tôi sẽ không bao giờ ngụ ý rằng loại s không được sử dụng. IMO, như tôi đã nói, chức năng freestanding là giải pháp tốt nhất. Các hàm tự do KHÔNG theo bất kỳ cách nào mâu thuẫn với mô hình của OOP trong C++ –

+0

Tất nhiên bạn đang đúng, sử dụng 'void *' không hàm ý điều đó! – v01pe

2

Không có cách nào để làm cho hàm có thể gọi là Math::SeedRandom (ngoại trừ việc thực hiện Math không có quy định của khóa học). Điều tốt nhất bạn có thể làm là di chuyển SeedRandom vào một lớp riêng biệt, không có khuôn mẫu hoặc chỉ sống với gọi nó là Math<whatever>::SeedRandom.

+0

Tôi muốn giữ nó trong cùng một lớp với các chức năng ngẫu nhiên, nhưng cảm ơn vì đã chỉ ra rằng nó không thể theo cách khác. – v01pe

0

Tôi rất hoài nghi về một lớp được gọi là "Toán" vì tôi thấy khó tưởng tượng một trường hợp "Toán". Từ những âm thanh của nó, bạn có thể muốn sử dụng một không gian tên với một số hàm mẫu miễn phí. Rằng bạn đang gặp vấn đề này có thể là một dấu hiệu cho thấy có lẽ bạn không nên làm những gì bạn đang làm.

C++ là ngôn ngữ đa mô hình và do đó không ép buộc mọi thứ trở thành một phần của đối tượng, không giống như các ngôn ngữ như Java.

+0

Vấn đề là, lớp này cũng chứa một số 'const', được sử dụng bên trong các hàm.Ngoài ra hàm tôi đã đề cập ở trên là hàm duy nhất, không cần mẫu. Tôi biết nó không phải là cách tốt nhất có thể để làm điều này, và tôi di chuyển refactor nó một ngày, nhưng bây giờ nó hoàn toàn phục vụ mục đích của nó. – v01pe

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