Посмотрите пример кода ниже:
class A
{
private:
class B
{
public:
foobar();
};
public:
foo();
bar();
};
В классе A и реализации B:
A::foo()
{
//do something
}
A::bar()
{
//some code
foo();
//more code
}
A::B::foobar()
{
//some code
foo(); //<<compiler doesn't like this
}
Компилятор отмечает вызов к нечто () в рамках метода foobar (). Ранее, я имел нечто () как функция члена парламента, не занимающего официального поста класса A, но изменился на общественность, предполагающую, что функция B не видит его. Конечно, это не помогло. Я пытаюсь снова использовать функциональность, обеспеченную методом A. Почему компилятор не позволяет этот вызов функции? Поскольку я вижу его, они - часть того же класса (A) включения. Я думал, что вопрос доступности для вложенного класса meebers для включения класса в стандартах C++ был решен.
Как я могу достигнуть того, что я пытаюсь обойтись без перезаписи того же метода (нечто ()) для B, который хранение B вложило в A?
Я использую VC ++ компилятор ver-9 (Visual Studio 2008).Спасибо за помощь.
foo()
является нестатической функцией-членом A
, и вы пытаетесь вызвать ее без экземпляра.
Вложенный класс B
- это отдельный класс, который имеет только некоторые привилегии доступа и не имеет никаких специальных знаний о существующих экземплярах A
.
Если B
нужен доступ к A
, вы должны дать ему ссылку на него, например:
class A {
class B {
A& parent_;
public:
B(A& parent) : parent_(parent) {}
void foobar() { parent_.foo(); }
};
B b_;
public:
A() : b_(*this) {}
};
Если вы хотите повторно использовать функциональность из A, вы должны наследовать от A, а не размещать B внутри него.
Это автоматическая, хотя, возможно, непереносимая уловка (хотя работала на VC ++ с 6.0). Класс B должен быть членом класса A, чтобы это работало.
#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();
};