StackMyFlow
StackMyFlow

Reputation: 103

Nested class design C++ virtual

I have a design problem in my application. I am quite new to the concept of virtual methods, inheritance and so forth & can't get it to run properly.

This is the situation:

I have a class called UI_Brainwash (pure coincidence) in which I have nested a second class SoundReciver.

class UI_BRAINWASH : public wxDialog
{
public:
    UI_BRAINWASH(wxWindow* parent,const wxString& title,double sec);
    virtual ~UI_BRAINWASH();

    void OnTimer(wxTimerEvent& event);      
    void StartLoop();

    class Soundreciver : public irrklang::ISoundStopEventReceiver
    {
                Soundreciver();
        // why is this not allowed?!
                Soundreciver(UI_BRAINWASH* par){this->parent = par;}
        virtual void OnSoundStopped(ISound* sound, E_STOP_EVENT_CAUSE reason, void* userData);

    public: // or private: doesn't change it -> compiler still complains
        UI_BRAINWASH* parent;

    };

private:
    wxTimer* m_timer;

Inside my Brainwash class I play a sound and once the sound has been played OnSoundStopped() is called, which is a virtual method of the abstract irrklang::ISoundStopEventReceiver Class.

http://www.ambiera.com/irrklang/docu/classirrklang_1_1_i_sound_stop_event_receiver.html

In that method I would like to start a wxTimer which is a member of the UI_Brainwash class, the problem is I can't access the variables of the class without having a handle to it (or can i ?) so I thought of writing a constructor:

Soundreciver(UI_BRAINWASH* par){this->parent = par;}

but when I compile that with VC2008 I get the following error:

UI_BRAINWASH::Soundreciver::Soundreciver' : cannot access private member declared in class 'UI_BRAINWASH::Soundreciver' : see declaration of 'UI_BRAINWASH::Soundreciver::Soundreciver' : see declaration of 'UI_BRAINWASH::Soundreciver'

How do I solve this conundrum?

Thank you for your time / suggestions

Upvotes: 0

Views: 171

Answers (2)

user405725
user405725

Reputation:

Nested classes can access non-public members of their parents but parents cannot access children's non-public members. There are only a few ways to fix it, really. Change protection level for members you want to access (i.e. do not make Soundreciver() and OnSoundStopped() all of the sudden become private). Or use friend keyword to allow access to non-public members for certain classes and/or functions.

Upvotes: 1

Nemanja Boric
Nemanja Boric

Reputation: 22157

The message you got is not the message about accessing private variable parent, but about accessing the constructor of the Soundreceiver. You need to make your Soundreceiver constructors public.

class Soundreciver : public irrklang::ISoundStopEventReceiver
{
 public:
    Soundreciver();
    // why is this not allowed?!
    Soundreciver(UI_BRAINWASH* par){this->parent = par;}
    virtual void OnSoundStopped(ISound* sound, E_STOP_EVENT_CAUSE reason, void* userData);

 private: // or private: doesn't change it -> compiler still complains
    UI_BRAINWASH* parent;

};

Other way would be to declare UI_BRAINWASH friend of the Soundreciver class, as Vlad pointed out.

Upvotes: 2

Related Questions