Я пытаюсь изучить C++ с помощью wxWidgets. До сих пор все мои программы были написаны на простой C (нет необходимости в объектах), vba, bash - как вы видите, я не программист.Незаконная ссылка на нестатический элемент или нерешенный внешний символ
Даже если этот пример в рамках WxWidgets это вообще C++ проблемы (на самом деле она моя проблема с ++ ;-)
Основных окон есть меню-бар с настройкой подменит/Communication. я определил класс, который для основного кадра в startup.h:
class startUp: public wxFrame
{
DECLARE_CLASS(startUp)
DECLARE_EVENT_TABLE()
public:
startUp();
startUp(wxWindow* parent, wxWindowID id = SYMBOL_....
~startUp();
void OnMENUCommunicationClick(wxCommandEvent& event);
....
void SetDevName(const wxString& devname);
protected:
static wxString devName;
};
и startup.cpp:
....
void startUp::SetDevName(const wxString& devname)
{
devName=_T(devname);
}
OnMENUCommunicationClick вызывает диалог, который должен вернуть имя устройства, выбранного в wxChoice (кстати, подача работ wxChoice). Этот диалог определен в другом классе:
#include "startup.h"
class Communication: public wxFrame
{
....
void Communication::CreateControls();
protected:
wxArrayString portChoiceStrings;
communication.cpp:
...
void Communication::CreateControls()
std::vector<std::string> ports;
int count = ScanSerialPorts(ports, true);
for(int i = 0; i < count; i++) {
portChoiceStrings.Add(wxString(ports[ i ].c_str(), wxConvUTF8));
}
portChoice = new wxChoice(itemPanel2, ID_ComportSet, wxPoint(108, 25), wxSize(55, -1), portChoiceStrings, 0);
portChoice->SetSelection(0);
....
}
void Communication::OnOKClick(wxCommandEvent& event)
{
startUp::SetDevName(_T(portChoiceStrings[portChoice->GetSelection()]));
//startUp::SetDevName(wxT(""));
Destroy();
}
Теперь к моей проблеме, я надеялся, что OnOKClick вернется к Startup выбранного устройства. У меня есть: c2352 незаконный вызов нестатической функции-члена. Поскольку член startUp не инициализирован, мой вариант состоял в том, чтобы изменить в startup.h как функции, так и переменные на статические.
static void SetDevName(const wxString& devname);
static wxString devName;
Вещи улучшились - все файлы компиляции, но линкер говорит неразрешенный внешний символ «защищенный: статический класс wxString Startup :: имя_устройства». Перемещение devName от охраняемого до общественности ничего не меняет.
Может ли кто-нибудь объяснить мне, что такое «правильный» способ передачи значений между классами? Я бы не хотел использовать глобальные переменные для его решения. По-видимому, это зло.
это один (диалоговое окно вызывает значение перед закрытием). Если ваше диалоговое окно немодально, у вас должна быть какая-то ссылка. otoh, если ваше диалоговое окно является модальным, для вашего объекта фрейма может быть больше смысла показывать его , затем прочитайте значение из него, когда оно вернет результат. Оба подхода работают. Я бы предпочел передать ссылку на конструктор диалогового окна, потому что это показывает диалоговое окно * требуется * ссылка для правильной работы. – araqnid