2012-01-03 2 views
0

Я пытаюсь изучить 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 от охраняемого до общественности ничего не меняет.

Может ли кто-нибудь объяснить мне, что такое «правильный» способ передачи значений между классами? Я бы не хотел использовать глобальные переменные для его решения. По-видимому, это зло.

ответ

1

Я нашел решение. Я удалил слово static из определений.

В классе запуска после Initialize диалогового окна Я добавить вызов функции setLink:

void startUp::OnMENUCommunicationClick(wxCommandEvent& event) 
    { 
    Communication* window = new Communication(this,ID_COMMUNICATION, _("Communication Settings")); 
    window->setLink(this); 
    int returnValue = window->Show(); 
    } 

чем в классе Communication Я добавил функцию setLink ссылки, которая хранит указатель основных окно:

void Communication::setLink(startUp* papi) 
    { 
    this->m_link = papi; 
    } 

, которые я мог бы использовать в OnSetClick:

void Communication::OnSetClick(wxCommandEvent& event) 
    { 
    m_link->SetDevName(_T(portChoiceStrings[portChoice->GetSelection()])); 
    Destroy(); 
    } 

Переменная m_link была определена в сообщении в качестве члена класса StartUp:.

startUp* m_relative; 

Все работает (т.е. программа компилирует и ссылки без ошибок и переменной имя_устройства из Startup-кадра устанавливается значение считанного из меню Communication

+0

это один (диалоговое окно вызывает значение перед закрытием). Если ваше диалоговое окно немодально, у вас должна быть какая-то ссылка. otoh, если ваше диалоговое окно является модальным, для вашего объекта фрейма может быть больше смысла показывать его , затем прочитайте значение из него, когда оно вернет результат. Оба подхода работают. Я бы предпочел передать ссылку на конструктор диалогового окна, потому что это показывает диалоговое окно * требуется * ссылка для правильной работы. – araqnid

Смежные вопросы