通过引用另一个向量传递向量 class/file
Passing vector by reference to another class/file
我有两套header+源文件。一个带有主 GUI class,另一个带有派生 GUI class(主 window 打开第二个 window)。
在 Main class 我有一个字符串向量。我可以通过调用 Derived class 中的函数并通过引用传递该向量来传递该向量。我可以在此函数中使用和更新该向量,并且更改将在 Main class/file 中可用。到目前为止一切顺利。
接下来我想做的是在 Derived class 的所有函数中使用这个通过引用向量传递的值。
到目前为止,我在 header+source 的“通用”集合中创建了 'extern' 向量。
这使它成为一个全局向量,虽然它可以工作,但它不是最优雅的方式。
是否有另一种方法使矢量可用于派生 GUI class/file 中的所有功能(以及稍后在主 GUI class/file 中可用的 add/edit 元素) ?
MainFrame.h
class wxMainFrame: public GUIFrame
{
public:
wxMainFrame(wxFrame *frame);
~wxMainFrame();
DerivedFrame *m_DerivedFrame;
private:
std::vector<wxString> vwsM3;
....etc
}
DerivedFrame.h
class DerivedFrame: public OtherFrane
{
public:
DerivedFrame( wxWindow* parent );
~DerivedFrame();
private:
std::vector<wxString> vwsM4;
void PassVector(std::vector<wxString> &vwsM);
void USEvwsM();
....etc
}
MainFrame.cpp
wxMainFrame::wxMainFrame(wxFrame *frame) : GUIFrame(frame)
{
m_DerivedFrame = new DerivedFrame(this);
m_DerivedFrame->PassVector(&vwsM3);
}
DerivedFrame.cpp
DerivedFrame::DerivedFrame ( wxWindow* parent ) : OtherFrame( parent )
{
//
}
void DerivedFrame::PassVector(std::vector<wxString> &vwsM)
{
vwsM.push_back("Something");
}
void USEvwsM()
{
// ??
}
OnInit()(矢量 vwsM3 在这里未知,因为它在单独的 header+源文件中)
IMPLEMENT_APP(wxMainApp);
bool wxMainApp::OnInit()
{
wxMainFrame* frame = new wxMainFrame(0L);
frame->SetIcon(wxICON(aaaa)); // To Set App Icon
frame->Show();
return true;
}
使用全局矢量是不好的做法,但无论如何对于像矢量这样的设置来说是典型的。
当我理解正确时,您要共享的矢量在基础中是这样的
struct base {
std::vector<std::string>& data;
base(std::vector<std::string>& init) : data(init) {}
};
struct derived : base {
derived(std::vector<std::string>& init) : base(init) {}
void have_fun_with_VectorOfStrings();
};
它可以在派生 class 中直接访问,或者任何可以访问派生 class 之一的实体。
不确定您是否正在寻找其他方法,例如 singleton pattern:
class coolStuff {
public:
std::vector<std::string> data;
static coolStuff& get() {
static coolStuff instance;
return instance;
}
private:
coolStuff () {
// constructor called once using "get", so can be used for initialization
}
};
这将在您需要的任何地方简单地调用。由于仅存在 1 个实例,因此它可能是实现相同目标的更好方法。
coolStuff::get().data.push_back("add a new string");
您同时分享了一个代码示例,因此您的示例看起来像上面的方法 1。
class wxMainFrame: public GUIFrame {
public:
wxMainFrame(wxFrame *frame, std::vector<wxString>& vwsM3);
private:
std::vector<wxString>& vwsM3;
};
wxServerFrame::wxServerFrame(wxFrame *frame, std::vector<wxString>& _vwsM3) : GUIFrame(frame)
, vwsM3(_vwsM3)
{
m_DerivedFrame = new DerivedFrame(this, _vwsM3);
// m_DerivedFrame->PassVector(&vwsM3); // not needed anymore
}
// same for further inherited classes
如果我可以添加旁注:看起来您正在做一些 graphic-like 的事情,因此还应考虑性能:尽量避免像 new、mallcoc 等动态分配,因为这是一个操作很慢。优化可能是使用 class 中的成员,而不是在运行时分配给成员指针。
- 为了派生class再增加一个指针字段:
class DerivedFrame: public OtherFrame {
.......
private:
std::vector<wxString> * pvwsM3 = nullptr;
.......
};
- 修改 PassVector() 方法来填充指针:
void DerivedFrame::PassVector(std::vector<wxString> & vwsM) {
pvwsM3 = &vwsM;
}
- 现在使用指针:
void DerivedFrame::USEvwsM() {
assert(pvwsM3); // Check that we don't have null pointer, you may throw exception instead.
pvwsM3->push_back("Something");
}
- 其余代码与您的相同。或者,您可以将向量传递给 DerivedFrame 的构造函数,这比单独调用 PassVector() 更可靠(您可能忘记调用,而构造函数您总是调用):
DerivedFrame::DerivedFrame(wxWindow* parent, std::vector<wxString> & vwsM)
: OtherFrame( parent ) {
this->PassVector(vwsM);
}
- 如果仅将字符串向量传递给构造函数,则不需要指针,而是在派生 class 中引用,因此不用指针字段
class DerivedFrame: public OtherFrame {
std::vector<wxString> * pvwsM3 = nullptr;
.......
};
制作参考字段
class DerivedFrame: public OtherFrame {
std::vector<wxString> & rvwsM3;
.......
};
然后删除 PassVector() 方法并在构造函数中添加引用初始化:
DerivedFrame::DerivedFrame(wxWindow* parent, std::vector<wxString> & vwsM)
: OtherFrame( parent ), rvwsM3(vwsM) {}
并将其用作引用(不像指针引用不需要检查是否为空):
void DerivedFrame::USEvwsM() {
rvwsM3.push_back("Something");
}
引用与指针相比有两个优点——不能忘记初始化,因为引用不需要调用PassVector(),也不需要检查它是否为null,不像检查指针(引用永远不会为空)。但是引用只能在构造函数中初始化,而指针可以稍后初始化,在构造对象之后很晚。
我有两套header+源文件。一个带有主 GUI class,另一个带有派生 GUI class(主 window 打开第二个 window)。
在 Main class 我有一个字符串向量。我可以通过调用 Derived class 中的函数并通过引用传递该向量来传递该向量。我可以在此函数中使用和更新该向量,并且更改将在 Main class/file 中可用。到目前为止一切顺利。
接下来我想做的是在 Derived class 的所有函数中使用这个通过引用向量传递的值。 到目前为止,我在 header+source 的“通用”集合中创建了 'extern' 向量。 这使它成为一个全局向量,虽然它可以工作,但它不是最优雅的方式。
是否有另一种方法使矢量可用于派生 GUI class/file 中的所有功能(以及稍后在主 GUI class/file 中可用的 add/edit 元素) ?
MainFrame.h
class wxMainFrame: public GUIFrame
{
public:
wxMainFrame(wxFrame *frame);
~wxMainFrame();
DerivedFrame *m_DerivedFrame;
private:
std::vector<wxString> vwsM3;
....etc
}
DerivedFrame.h
class DerivedFrame: public OtherFrane
{
public:
DerivedFrame( wxWindow* parent );
~DerivedFrame();
private:
std::vector<wxString> vwsM4;
void PassVector(std::vector<wxString> &vwsM);
void USEvwsM();
....etc
}
MainFrame.cpp
wxMainFrame::wxMainFrame(wxFrame *frame) : GUIFrame(frame)
{
m_DerivedFrame = new DerivedFrame(this);
m_DerivedFrame->PassVector(&vwsM3);
}
DerivedFrame.cpp
DerivedFrame::DerivedFrame ( wxWindow* parent ) : OtherFrame( parent )
{
//
}
void DerivedFrame::PassVector(std::vector<wxString> &vwsM)
{
vwsM.push_back("Something");
}
void USEvwsM()
{
// ??
}
OnInit()(矢量 vwsM3 在这里未知,因为它在单独的 header+源文件中)
IMPLEMENT_APP(wxMainApp);
bool wxMainApp::OnInit()
{
wxMainFrame* frame = new wxMainFrame(0L);
frame->SetIcon(wxICON(aaaa)); // To Set App Icon
frame->Show();
return true;
}
使用全局矢量是不好的做法,但无论如何对于像矢量这样的设置来说是典型的。
当我理解正确时,您要共享的矢量在基础中是这样的
struct base {
std::vector<std::string>& data;
base(std::vector<std::string>& init) : data(init) {}
};
struct derived : base {
derived(std::vector<std::string>& init) : base(init) {}
void have_fun_with_VectorOfStrings();
};
它可以在派生 class 中直接访问,或者任何可以访问派生 class 之一的实体。
不确定您是否正在寻找其他方法,例如 singleton pattern:
class coolStuff {
public:
std::vector<std::string> data;
static coolStuff& get() {
static coolStuff instance;
return instance;
}
private:
coolStuff () {
// constructor called once using "get", so can be used for initialization
}
};
这将在您需要的任何地方简单地调用。由于仅存在 1 个实例,因此它可能是实现相同目标的更好方法。
coolStuff::get().data.push_back("add a new string");
您同时分享了一个代码示例,因此您的示例看起来像上面的方法 1。
class wxMainFrame: public GUIFrame {
public:
wxMainFrame(wxFrame *frame, std::vector<wxString>& vwsM3);
private:
std::vector<wxString>& vwsM3;
};
wxServerFrame::wxServerFrame(wxFrame *frame, std::vector<wxString>& _vwsM3) : GUIFrame(frame)
, vwsM3(_vwsM3)
{
m_DerivedFrame = new DerivedFrame(this, _vwsM3);
// m_DerivedFrame->PassVector(&vwsM3); // not needed anymore
}
// same for further inherited classes
如果我可以添加旁注:看起来您正在做一些 graphic-like 的事情,因此还应考虑性能:尽量避免像 new、mallcoc 等动态分配,因为这是一个操作很慢。优化可能是使用 class 中的成员,而不是在运行时分配给成员指针。
- 为了派生class再增加一个指针字段:
class DerivedFrame: public OtherFrame {
.......
private:
std::vector<wxString> * pvwsM3 = nullptr;
.......
};
- 修改 PassVector() 方法来填充指针:
void DerivedFrame::PassVector(std::vector<wxString> & vwsM) {
pvwsM3 = &vwsM;
}
- 现在使用指针:
void DerivedFrame::USEvwsM() {
assert(pvwsM3); // Check that we don't have null pointer, you may throw exception instead.
pvwsM3->push_back("Something");
}
- 其余代码与您的相同。或者,您可以将向量传递给 DerivedFrame 的构造函数,这比单独调用 PassVector() 更可靠(您可能忘记调用,而构造函数您总是调用):
DerivedFrame::DerivedFrame(wxWindow* parent, std::vector<wxString> & vwsM)
: OtherFrame( parent ) {
this->PassVector(vwsM);
}
- 如果仅将字符串向量传递给构造函数,则不需要指针,而是在派生 class 中引用,因此不用指针字段
class DerivedFrame: public OtherFrame {
std::vector<wxString> * pvwsM3 = nullptr;
.......
};
制作参考字段
class DerivedFrame: public OtherFrame {
std::vector<wxString> & rvwsM3;
.......
};
然后删除 PassVector() 方法并在构造函数中添加引用初始化:
DerivedFrame::DerivedFrame(wxWindow* parent, std::vector<wxString> & vwsM)
: OtherFrame( parent ), rvwsM3(vwsM) {}
并将其用作引用(不像指针引用不需要检查是否为空):
void DerivedFrame::USEvwsM() {
rvwsM3.push_back("Something");
}
引用与指针相比有两个优点——不能忘记初始化,因为引用不需要调用PassVector(),也不需要检查它是否为null,不像检查指针(引用永远不会为空)。但是引用只能在构造函数中初始化,而指针可以稍后初始化,在构造对象之后很晚。