2012-01-03 2 views
0

私はwxWidgetsでC++を学ぼうとしています。今まで私のすべてのプログラムは普通のC(オブジェクトの必要がない)、vba、bashで書かれていました。私がプログラマーではないことがわかります。この例では、wxWidgetsのフレームに、それは実際にはC++ ;-)非静的メンバーまたは未解決の外部シンボルへの不正な参照

のメインウィンドウでの地雷問題の一般的なC++の問題(だいた場合であっても

は、サブメニューの設定/通信でメニューバーを併設しています。 私は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で選択されたデバイスの名前(btw、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スタートアップ選択したデバイスに戻ってくることを期待私の問題に。私は何を持っています: c2352非静的メンバー関数の不正な呼び出しです。 startUpのメンバーが初期化されていないので、私のオプションは、startup.hの関数と変数を静的に変更することでした。

static void SetDevName(const wxString& devname); 
static wxString devName; 

物事が改善 - すべてのファイルがコンパイルが、リンカは、未解決の外部シンボル「保護:静的クラスwxStringスタートアップ:: DEVNAME」と言うを。 devNameをprotectedからpublicに変更しても、何も変更されません。

誰かがクラス間で値を渡す「適切な」方法を教えていただけますか?私はそれを解決するためにグローバル変数を使用したくないです。どうやらこれらは悪いです。

答えて

1

解決策が見つかりました。定義から単語を削除しました。私は、メインのポインタを格納したリンク機能setLinkを追加したコミュニケーションクラスよりも

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

:私はsetLinkを関数の呼び出しを追加しましたダイアログウィンドウの初期化後クラス起動

窓:私はOnSetClickに使用することができ

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

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

m_link変数は、で定義されています。起動クラスのメンバーとしてH

startUp* m_relative; 

すべての作品(つまり、プログラムのコンパイルとリンクエラーが発生することなく、スタートアップ・フレームからDEVNAME変数はコミュニケーションメニューから読み込まれた値に設定されている

+0

一つだという。あなたのダイアログボックスが非モーダルであれば、あなたはそのようなリンクを持っていなければなりません。ダイアログボックスがモーダルであれば、あなたのフレームオブジェクトがそれを表示するのがより理にかなっているかもしれません。 、それから結果を返すときに値を読んでください。どちらも近づきます。ダイアログボックスのコンストラクタへのリンクを渡すことをお勧めします。なぜなら、ダイアログボックス*適切に動作するためのリンクが必要です。 – araqnid