对非静态成员或未解析的外部符号的非法引用

发布于 2024-12-24 01:49:04 字数 2178 浏览 0 评论 0原文

我正在尝试使用 wxWidgets 学习 C++。到目前为止,我所有的程序都是用纯 C(不需要对象)、vba、bash 编写的 - 正如你所见,我不是程序员。

即使这个例子是在 wxWidgets 框架中,它也是一般的 C++ 问题(实际上这是我的 C++ 问题;-)

主窗口有一个带有子菜单设置/通信的菜单栏。 中为主框架定义了一个类:

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.hstartup.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;

事情有所改善 - 所有文件都编译,但链接器显示未解析的外部符号“protected: static class wxString startUp::devName”。将 devName 从受保护状态移至公共状态不会改变任何事情。

有人可以解释一下在类之间传递值的“正确”方法是什么吗?我不想使用全局变量来解决它。显然这些都是邪恶的。

I'm trying to learn c++ with wxWidgets. Till now all my programs were written in plain C (no needs for objects), vba, bash - as you see I'm not programer.

Even if this example is in frame of wxWidgets it's general c++ problem (actually it's mine problem with c++ ;-)

The main windows has a menu-bar with sub-menu Settings/Communication.
I have defined a class that for a main frame in 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;
};

and startup.cpp:

....
void startUp::SetDevName(const wxString& devname) 
{
    devName=_T(devname);
}

The OnMENUCommunicationClick calls a dialog that should return the name of the device selected in wxChoice (btw, feeding of the wxChoice works). This dialog defined in another class:

#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();
}

Now to my problem I hoped that OnOKClick would return to startUp selected device. What I've got is:
c2352 illegal call of non-static member function. As the member of startUp is not initialized my option was to change in startup.h both function and variable to static.

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

The things improved - all files compile but linker says unresolved external symbol "protected: static class wxString startUp::devName". Moving devName from protected to public doesn't change a thing.

Can somebody explain me what is "the proper" way of passing values between classes? I wouldn't like to use global variables to solve it. Apparently these are evil.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

西瓜 2024-12-31 01:49:04

我已经找到解决方案了。我已从定义中删除了“静态”一词。

在初始化对话框窗口后的启动类中,我添加了对函数 setLink 的调用:

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

比在通信类中,我添加了一个存储主窗口指针的链接函数 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变量在communication.h中定义为startUp类的成员:

startUp* m_relative;   

一切正常(ie程序编译和链接没有错误并且启动帧中的 devName 变量设置为从通信菜单读取的值。

I've found solution. I've removed word static from definitions.

In class startup after initialize of dialog window I've add a call to function setLink:

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

Than in class Communication I've added a link function setLink that stores pointer of main window:

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

which I could use in OnSetClick :

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

The m_link variable was defined in communication.h as a member of startUp class:

startUp* m_relative;   

Everything works (i.e. program compiles and links without errors and the devName variable from startUp-Frame is set to value read from Communication menu.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文