2011-12-21 65 views
5

Vì vậy, đây là tình huống: Tôi đang sử dụng C++, SDL và GLConsole kết hợp. Tôi có một lớp, SDLGame, trong đó có Init(), Loop(), Render() v.v ... về cơ bản, nó giữ logic cho lớp trò chơi của tôi.
GLConsole là một thư viện tốt đẹp cho đến nay - nó cho phép tôi xác định CVars và như vậy, ngay cả trong lớp SDL của tôi. Tuy nhiên, khi xác định lệnh, tôi phải chỉ định một số ConsoleFunc, được nhập làChuyển hàm con trỏ thành thành viên làm con trỏ tới hàm

typedef bool (*ConsoleFunc)(std::vector<std::string> *args); 

Đủ đơn giản. Tuy nhiên, như tôi đã nói, các hàm của tôi là tất cả trong lớp của tôi, và tôi biết tôi không thể chuyển các hàm con trỏ tới lớp như các đối số trỏ đến hàm. Tôi không thể định nghĩa các hàm tĩnh hoặc tạo ra các hàm bên ngoài lớp của tôi vì một số ConsoleFunc này phải truy cập các thành viên của lớp dữ liệu để có ích. Tôi muốn giữ nó OOP, vì - tốt, OOP là tốt đẹp.

Vâng, tôi thực sự gặp sự cố này "đã giải quyết" - nhưng nó cực kỳ xấu xí. Tôi chỉ có một thể hiện của SDLGame được khai báo dưới dạng một biến ngoài, và sử dụng nó trong lớp ConsoleFuncs/main của tôi.

Vì vậy, câu hỏi đặt ra là: Có cách nào để làm điều này không ngu ngốc và câm như cách tôi đang làm không? (Ngoài ra: có một thư viện giao diện điều khiển như GLConsole hỗ trợ SDL và có thể làm những gì tôi mô tả không?)

Trả lời

7

Nếu giao diện duy nhất bạn có là con trỏ hàm đó, thì bạn bị say.

Chức năng thành viên cần một con trỏ this để được gọi và nếu bạn không có cách nào vượt qua điều đó, bạn sẽ không may mắn (tôi đoán con trỏ std::vector<std::string>* args là thông tin bạn nhận được từ thư viện).

Nói cách khác, mặc dù thư viện đó sử dụng các thùng chứa C++, nó không phải là một thư viện C++ tốt, vì nó dựa vào các hàm miễn phí cho các cuộc gọi lại. Thư viện C++ tốt sẽ sử dụng boost::function hoặc một cái gì đó tương tự hoặc ở ít nhất cho phép bạn vượt qua con trỏ void* user_data được chuyển đến hàm gọi lại của bạn. Nếu bạn có điều đó, bạn có thể vượt qua con trỏ this của lớp của bạn, đưa nó trở lại bên trong hàm gọi lại và gọi hàm thành viên thích hợp.

+0

Vâng dang. Dù sao cũng cảm ơn bạn. Bạn có đề xuất cho một thư viện khác để sử dụng không? Tôi đã nhìn vào OGLConsole, nhưng nó có cùng một vấn đề. – Chaosed0

+0

@user: Rất tiếc, không có đề xuất thư viện nào. :/ – Xeo

+0

Tôi khuyên bạn nên sử dụng dữ liệu người dùng 'void *' ". Chắc chắn, nó không phải là đẹp như một ngôn ngữ hiện đại 'đại biểu', nhưng nó là một con đường an toàn để có vì nó là mã của bạn đăng ký gọi lại và dữ liệu người dùng như một cặp. Vì vậy, nó là 100% an toàn để chỉ cast 'void *' đến loại lớp thích hợp bởi vì callback được thiết lập với ý định đó trong tâm trí. – TheBuzzSaw

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