简体   繁体   中英

Calling private functions in nested classes

I've developed a class, let's call it foo. In the header file, I've opted to have a class containing all of foo's private members in the private: section. This way, if I have to edit any private members of foo, I don't have to recompile every source file which uses foo.h. It's set up as such:

#ifndef FOO_H
#define FOO_H

class fooData;

class foo
{
   private:
      fooPrivate *prv; // This class stores foo's private members
   public:
      foo(); // Default constructor
      void bar();
}

#endif

My foo.cpp class looks like this:

#include "foo.h"

class fooPrivate // Class which stores foo's private members
{
   public:
      void doMagic();
}

foo::foo()
{
   prv = new fooPrivate; // Instantiate fooPrivate
   prv->doMagic();
}

void foo::magic() // This is a public member function of foo
{
   std::cout << "Magic!" << std::endl;
}

void fooPrivate::doMagic() // This is a function of private member fooPrivate
{
   magic(); // I want to call a public member of foo here
}

Most of you already know the error I'm going to to from attempting to call magic() from doMagic():

error: 'magic' was not declared in this scope

And, changing the call to foo::magic() results in:

error: cannot call member function 'void foo::magic()' without onject

Now, I would really like to avoid instantiating an object of type foo, inside an object of type fooPrivate, which itself results from an instantiation of an object of type foo... So, is there a way to call the public member function magic() from a public member function of fooPrivate?

When you create fooPrivate, pass in a reference to foo as part of the constructor:

foo::foo()
{
  prv= new fooPrivate( * this) ;
}

class fooPrivate
{
  foo & foo_ ;
  ...
}

fooPrivate::fooPrivate( foo & aparen) : foo_( aparen ) { }

Then in doMagic() just call it by reference:

void fooPrivate::doMagic()
{
  foo_.magic() ;
}

Also, store fooPrivate in a unique_ptr so that when foo is destroyed, fooPrivate is destroyed along with it:

class foo
{
  private:
    std::unique_ptr<fooPrivate> prv ;

Which for convenience you could initialize like:

foo::foo() : prv( new fooPrivate( * this ) ) { }

By the way, I don't recommend calling out to prv->magic() inside the constructor if it's then going to call back into the still being created foo with the call to doMagic .

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