简体   繁体   中英

Passing vector by reference to another class/file

I have 2 sets of header+source files. One with the Main GUI class and the other with a Derived GUI class (Main window that opens a second window).

In the Main class I have a vector of strings. I can pass that vector by reference by calling a function in the Derived class and pass it by reference. I can use and update that vector in this function and the changes will be available in the Main class/file. So far so good.

The next thing I would like to do is use this passed by reference vector in all functions in the Derived class. Up to now, I created and 'extern' vector in a "common" set of header+source. This make it a global vector, and although its working, it is not the most elegant way.

Is there an alternative way to make the vector available to all functions in the Derived GUI class/file (and add/edit elements that are available in the Main GUI class/file later on)?

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() (The vector vwsM3 is not known here because its in a seperate header+source file)

IMPLEMENT_APP(wxMainApp);

bool wxMainApp::OnInit()
{
    wxMainFrame* frame = new wxMainFrame(0L);
    frame->SetIcon(wxICON(aaaa)); // To Set App Icon
    frame->Show();

    return true;
}

Having a global vector is bad practice, but anyhow typical for a settings like vector.

When I understand right, the vector you want to share, is known in the base like this

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

it can be directly accessed in derived class, or any entity having access to one of the derived class.

Not sure if you might be looking for a different approach like the singleton pattern instead:

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
    }
};

This would be simply called anywhere you need it. Since only 1 instance exists, it might be a better approach to achieve the same.

coolStuff::get().data.push_back("add a new string");

You have shared a code example meanwhile, so your example would look like this applying approach 1 above.

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

If I may add a side note: It looks like you are doing some graphic-like stuff, so performance should be considered aswell: Try to avoid dynamic allocations like new, mallcoc, etc, since this is a very slow operation. An optimization might be to use a member in the class, instead of allocating to a member pointer at runtime.

  1. To derived class add one more pointer field:
class DerivedFrame: public OtherFrame {
    .......
    private:
        std::vector<wxString> * pvwsM3 = nullptr;
    .......
}
  1. Modify PassVector() method to fill pointer:
void DerivedFrame::PassVector(std::vector<wxString> & vwsM) {
    pvwsM3 = &vwsM;
}
  1. Use pointer now:
void DerivedFrame::USEvwsM() {
    assert(pvwsM3); // Check that we don't have null pointer, you may throw exception instead.
    pvwsM3->push_back("Something");
}
  1. Remaining code is same as you have. Alternatively you may pass vector to constructor of DerivedFrame, which is more reliable than calling PassVector() separately (which you may forget to call, while constructor you always call):
DerivedFrame::DerivedFrame(wxWindow* parent, std::vector<wxString> & vwsM)
    : OtherFrame( parent ) {
    this->PassVector(vwsM);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM