Я провел последний год, изучая C ++ (используя C ++ Primer в качестве рекомендованного материала от https://stackoverflow.com/a/388282/1440199).. Я хотел научиться использовать ncurses для создания моей первой летающей сольной программы. Несмотря на то, что NCurses основан на C, онболее или менее малоизвестно, что встроенных оболочек ncurses C ++ существует . Однако документации для них практически не существует, есть файл demo.cc, который я использовал в качестве основы, и несколько местпо всему Интернету . В любом случае, я сделал свой итоговый экзамен, так сказать, чтобы понять и использовать эти оболочки.
Проблема, с которой я сталкиваюсь, относится к типу "лучших практик программирования": из-заОтсутствие документированных примеров, я не уверен, что лучший способ создать подменю из системы начального меню демо .
Лучшая идея, которую я могу придумать, - это использовать пример способа в присоединение NCursesUserItem ncurses ++ к пункту меню . Будет ли указатель пользователя указателем на предыдущий класс меню? В NCurses,Вы можете публиковать и отменять публикацию меню, поэтому я также предполагаю, что я хочу «отменить публикацию» предыдущего меню, когда новое «отправляет», поэтому при отображении нового я хотел указатель на предыдущее меню.
Типичный безопасный способ присоединения пользовательских данных (для set_item_userptr) к пункту меню:
template<class T> class SubMenu : public NCursesUserItem<T>
{
public:
SubMenu (const char* p_name,
const T* p_UserData)
: NCursesUserItem<T>(p_name, static_cast<const char*>(0), p_UserData){}
virtual ~SubMenu() {}
bool action() {
// I believe I want to unpost the previous menu here
// before posting the new submenu?
NCursesUserItem<T>::UserData()->prev_menu()->unpost();
//This doesn't work, but its kind of what I want to do.
NCursesUserItem<T>::UserData()->post();
return FALSE;
}
};
Объект главного меню.Я создал здесь объект Submenu и передал ему «this» (указатель главного меню) в качестве аргумента.
class MainMenu : public NCursesMenu
{
private:
NCursesMenuItem** I;
Choice0Menu* u;
#define n_items 3
public:
MainMenu ()
: NCursesMenu (n_items+2, 25, (lines()-5)/2, (cols()-23)/2), I(0), u(0)
{
u = new Choice0Menu(this);
I = new NCursesMenuItem*[1+n_items];
I[0] = new SubMenu<Choice0Menu> ("Choice 0", u);
I[1] = new PadAction("Choice 1");
I[2] = new QuitItem();
I[3] = new NCursesMenuItem();
InitMenu(I, TRUE, TRUE);
}
};
Класс Choice0Menu, который должен содержать кнопку возврата для возврата в главное меню (I [2])
class Choice0Menu : public NCursesMenu
{
private:
NCursesMenuItem** I;
MainMenu* w;
#define n_items 3
public:
Choice0Menu (MainMenu* prev)
: NCursesMenu (n_items+2, 25, (lines()-5)/2, (cols()-23)/2), I(0), w(prev)
{
I = new NCursesMenuItem*[1+n_items];
I[0] = new ScanAction("Submenu Choice 0");
I[1] = new PadAction("Submenu Choice 1");
I[2] = new MainMenuAction("Go Back");
I[3] = new NCursesMenuItem();
InitMenu(I, TRUE, TRUE);
// returns the pointer to the prev object
MainMenu* prev_menu() const{
return w;
}
};
У меня просто много сомнений относительно этого способа, например, может быть, мне не нужно передавать весь указатель this в главное меню при создании подменю,просто пост и отстойники.И классы MainMenu и Choice0Menu очень похожи по функциям, так что, может быть, даже превратить их в один шаблонный класс?Так как Choice0Menu принимает MainMenu в качестве аргумента, может быть, для выбора любого типа меню нужно использовать T *.
Мой метод не кажется «чистым» способом программирования проблемы.
Спасибо за помощь.Я изучаю эту проблему почти 2 недели ...