Форум программистов, компьютерный форум CyberForum.ru

внук родительского класса не может работать с полями дедовского класса; почему? - C++

Восстановить пароль Регистрация
 
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
05.06.2011, 23:16     внук родительского класса не может работать с полями дедовского класса; почему? #1
Не всё так просто на самом деле. Непонятно, какую роль во всём этом играют шаблоны. Но к делу. Вот код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class base {
 public:
 base (){};
 public:
  int g;
};
 
 
template <class T>
class sinn: public base {
 public:
  sinn () {};
};
 
 
template <class T>
class vnuk: public sinn<T> {
 public:
  vnuk () {};
  void vnuk_ () {g= 8;};
};
 
int main() {
}
Так, компилятор говорит, что он впервые видит переменную g; не помогает и:
C++
1
base::g= 8;
При чём обратите внимание, переменная g объявлена как public!
Ладно, а теперь я даже не знаю, в какую сторону и копать. Убираем все упоминания о шаблонах:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class base {
 public:
 base (){};
 protected:
  int g;
};
 
 
class sinn: public base {
 public:
  sinn () {};
};
 
 
class vnuk: public sinn {
 public:
  vnuk () {};
  void vnuk_ () {g= 8;};
};
 
 
int main() {
}
...Всё компилится. При чём g теперь protected
В общем, ребята, мне нужно, чтобы скомпилилось именго с шаблоами, а какое отношение они имеют к g я ума не приложу, спасибо заранее.
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.06.2011, 23:16     внук родительского класса не может работать с полями дедовского класса; почему?
Посмотрите здесь:

C++ Сам вопрос: почему функция-член одного класса не вызывается из функции-члена другого класса?
C++ Как вызвать виртуальную функцию из дочернего класса, если она определена и вызывается в конструкторе РОДИТЕЛЬСКОГО класса?
C++ Почему сын может спокойно работать с полями privat отцовского класса (опять template <class T> воду мутит!)
Как сделать, чтобы функция класса могла работать с обьектами другого класса C++
C++ Почему в списке инициализации конструктора дочернего класса нельзя вызывать конструктор родительского через его пространство имён?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
grizlik78
Эксперт С++
 Аватар для grizlik78
1884 / 1416 / 102
Регистрация: 29.05.2011
Сообщений: 2,961
05.06.2011, 23:24     внук родительского класса не может работать с полями дедовского класса; почему? #2
Понятия не имею, должно это так быть, или нет, но используй
C++
1
sinn<T>::g
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
05.06.2011, 23:26     внук родительского класса не может работать с полями дедовского класса; почему? #3
Странно. У меня первый код скомпилировался...
grizlik78
Эксперт С++
 Аватар для grizlik78
1884 / 1416 / 102
Регистрация: 29.05.2011
Сообщений: 2,961
05.06.2011, 23:28     внук родительского класса не может работать с полями дедовского класса; почему? #4
Ну вот g++ 4.5.1 артачится чего-то.
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
05.06.2011, 23:31     внук родительского класса не может работать с полями дедовского класса; почему? #5
Хаа, действительно, g++ не нравится этот код, а майкрософт его спокойно глотает...
lemegeton
 Аватар для lemegeton
2910 / 1339 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
06.06.2011, 09:01     внук родительского класса не может работать с полями дедовского класса; почему? #6
Что-то мы с вами не догоняем про области видимости.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Base {
 public:
  int field_;
};
 
template <class Tp_>
class One: public Base {
 public:
  void MethodOne() {
    field_ = 0;
 }
};
 
template <class Tp_>
class Two: public One<Tp_> {
 public:
  void MethodTwo() {
    // field_ = 0;  // ошибка
    this->field_ = 0; // нормуль
  }
};
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.06.2011, 11:02     внук родительского класса не может работать с полями дедовского класса; почему?
Еще ссылки по теме:

Какие методы родительского класса не наследуются? C++
C++ Создать объект внутри класса, который может вызывать функцию этого класса
Может ли метод родительского класса обратиться к полю дочернего класса C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
CyBOSSeR
Эксперт C++
 Аватар для CyBOSSeR
2294 / 1664 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
06.06.2011, 11:02     внук родительского класса не может работать с полями дедовского класса; почему? #7
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Косяк действительно с областями видимости, using решает проблему:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Base {
 public:
  int field_;
};
 
template <class Tp_>
class One: public Base {
 public:
  void MethodOne() {
    field_ = 0;
 }
};
 
template <class Tp_>
class Two: public One<Tp_> {
 using Base::field_;
 
 public:
  void MethodTwo() {
    field_ = 0;  // ок
  }
};
Хм... За пределами класса все нормально видится:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Base {
 public:
  int field;
};
 
template <class T>
class One: public Base {
};
 
template <class T>
class Two: public One<T> {
};
 
int main()
{
  Two<int> two;
  two.field = 100; // ок
}
Добавлено через 39 минут
Есть идея почему так происходит, но, естественно, я могу ошибаться.
Дело в том, что компилятор до инстанцирования vnuk не знает, что есть g, так как могут иметь место специализации sinn, в которых g может быть чем угодно - методом, именем типа, другим полем и т.д. Т.е. получается то, чем будет являтся g будет зависеть от аргумента шаблона, а к зависимым именам применяются другие правила поиска.

Добавлено через 26 минут
Похоже, ответ таится здесь:
Цитата Сообщение от C++98 14.6.2.3
In the definition of a class template or in the definition of a member of such a template that appears outside of the template definition, if a base class of this template depends on a template-parameter, the base class scope is not examined during name lookup until the class template is instantiated
Добавлено через 33 минуты
В стандарте C++03 пункт 14.6.2.3 имеет несколько другую формулировку, и говорит о том что unqualified имена не ищутся в базовых шаблонных классах ни при определении класса ни при его инстанцировании, что собственно наблюдается в данном случае.
Yandex
Объявления
06.06.2011, 11:02     внук родительского класса не может работать с полями дедовского класса; почему?
Ответ Создать тему
Опции темы

Текущее время: 04:37. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru