Nested Class member function can't access function of enclosing class. Why?

僤鯓⒐⒋嵵緔 提交于 2019-11-29 03:08:17

foo() is a non-static member function of A and you are trying to call it without an instance.
The nested class B is a seperate class that only has some access privileges and doesn't have any special knowledge about existing instances of A.

If B needs access to an A you have to give it a reference to it, e.g.:

class A {
    class B {
        A& parent_;
    public:
        B(A& parent) : parent_(parent) {}
        void foobar() { parent_.foo(); }
    };
    B b_;
public:
    A() : b_(*this) {}
};

This is an automagic, albeit possibly nonportable trick (worked on VC++ since 6.0 though). Class B has to be a member of class A for this to work.

#ifndef OUTERCLASS
#define OUTERCLASS(className, memberName) \
    reinterpret_cast<className*>(reinterpret_cast<unsigned char*>(this) - offsetof(className, memberName))
#endif 

class A
{
private:
    class B
    {
    public:
        void foobar() {
           A* pA = OUTERCLASS(A, m_classB);
           pA->foo();
        }
    } m_classB;
public:
    foo();
    bar();
};

If you want to reuse functionality from A then you should inherit from A not nest B inside it.

Basically what Georg Fritzsche said

#include <iostream>
#include <cstring>
using namespace std;

class A
{
private:
    class B
    {
     A& parent_;
     public:
        //B();  //uncommenting gives error
        ~B();
        B(A& parent) : parent_(parent) {}

        void foobar() 
        { 
         parent_.foo();  
         cout << "A::B::foo()" <<endl; 
        }

        const std::string& foobarstring(const std::string& test) const 
        { 
         parent_.foostring(test); cout << "A::B::foostring()" <<endl;
        }
    };
public:
    void foo();
    void bar();
    const std::string& foostring(const std::string& test) const;
    A(); 
    ~A(){};
    B b_;
};

//A::B::B() {}; //uncommenting gives error
A::B::~B(){};

A::A():b_(*this) {}


void A::foo()
{
    cout << "A::foo()" <<endl;
}

const std::string& A::foostring(const std::string& test) const
{
    cout << test <<endl;
    return test;
}

void A::bar()
{
    //some code
    cout << "A::bar()" <<endl;
    foo();
    //more code
}

int main(int argc, char* argv[])
{
A a;
a.b_.foobar();
a.b_.foobarstring("hello");

return 0;
}

If you uncomment the default B constructor you would get an error

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!