Недопустимое использование нестатического элемента данных
Для кода, подобного этому:
class foo {
protected:
int a;
public:
class bar {
public:
int getA() {return a;} // ERROR
};
foo()
: a (p->param)
};
Я получаю эту ошибку:
invalid use of non-static data member 'foo::a'
в настоящее время переменная a
инициализируется в конструкторе foo
.
если я сделаю его статическим, тогда он говорит:
error: 'int foo::a' is a static data member; it can only be initialized at its definition
Однако я хочу передать значение a
в конструкторе.
Каково решение тогда?
Ответы
Ответ 1
В С++, в отличие от (скажем) Java, экземпляр вложенного класса не является неотъемлемо принадлежащим к любому экземпляру охватывающего класса. Таким образом, bar::getA
не имеет конкретного экземпляра foo
, чей a
он может возвращаться. Я предполагаю, что вам нужно что-то вроде:
class bar {
private:
foo * const owner;
public:
bar(foo & owner) : owner(&owner) { }
int getA() {return owner->a;}
};
Но даже для этого вам, возможно, придется внести некоторые изменения, потому что в версиях С++ до С++ 11, в отличие от (опять же, скажем) Java, вложенный класс не имеет специального доступа к его охватывающему классу, t элемент protected
a
. Это будет зависеть от вашей версии компилятора. (Hat-tip для Ken Wayne VanderLinde, указав, что С++ 11 изменил это.)
Ответ 2
В С++ вложенные классы не связаны ни с одним экземпляром внешнего класса. Если вы хотите, чтобы bar
имел доступ к нестационарным членам foo
, тогда bar
должен иметь доступ к экземпляру foo
. Может быть, что-то вроде:
class bar {
public:
int getA(foo & f ) {return foo.a;}
};
Или, может быть,
class bar {
private:
foo & f;
public:
bar(foo & g)
: f(g)
{
}
int getA() { return f.a; }
};
В любом случае вам необходимо явно убедиться, что у вас есть доступ к экземпляру foo
.
Ответ 3
Вложенный класс не знает о внешнем классе, а protected
не помогает. Вам нужно будет передать некоторую фактическую ссылку на объекты типа вложенного класса. Вы можете сохранить foo*
, но, возможно, достаточно ссылки на целое число:
class Outer
{
int n;
public:
class Inner
{
int & a;
public:
Inner(int & b) : a(b) { }
int & get() { return a; }
};
// ... for example:
Inner inn;
Outer() : inn(n) { }
};
Теперь вы можете создавать внутренние классы типа Inner i(n);
и вызывать i.get()
.
Ответ 4
Вы пытаетесь получить доступ к частному члену одного класса из другого. Тот факт, что bar-class объявлен в foo-классе, означает, что панель видима только внутри класса foo, но это еще один класс.
А что такое p- > param?
Собственно, неясно, что вы хотите делать