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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
kravam
быдлокодер
1694 / 881 / 44
Регистрация: 04.06.2008
Сообщений: 5,441
#1

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

05.06.2011, 23:16. Просмотров 645. Ответов 6
Метки нет (Все метки)

Не всё так просто на самом деле. Непонятно, какую роль во всём этом играют шаблоны. Но к делу. Вот код:
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++):

Почему сын может спокойно работать с полями privat отцовского класса (опять template <class T> воду мутит!) - C++
Сабж class otets { public: otets (){}; private: int znach; }; template &lt;class T&gt; class sinn: public otets {

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

Почему не выводятся данные родительского класса - C++
помогите с кодом не могу понять почему не выводит данные родительского класса при при вызове дочернего вот код тут все понятно...

Как вызвать виртуальную функцию из дочернего класса, если она определена и вызывается в конструкторе РОДИТЕЛЬСКОГО класса? - C++
Ну то есть так: есть родительский и дочерний класс, в родительском определен виртуальная функция и вызывается в его конструкторе (камень...

Почему в списке инициализации конструктора дочернего класса нельзя вызывать конструктор родительского через его пространство имён? - C++
Есть класс D и от него порождён класс Wd Тут вот например всё работает корректно (использую обращение ч/з пространство имён класса &quot;D::&quot; ...

Член класса управляемый не может относиться к типу класса неуправляемый - C++
Подскажите пожалуйста, что за ошибка &quot;Член класса управляемый не может относиться к типу класса неуправляемый&quot;? #include &lt;vector&gt; ...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
grizlik78
Эксперт С++
1908 / 1440 / 111
Регистрация: 29.05.2011
Сообщений: 2,996
05.06.2011, 23:24 #2
Понятия не имею, должно это так быть, или нет, но используй
C++
1
sinn<T>::g
silent_1991
Эксперт С++
4963 / 3039 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
05.06.2011, 23:26 #3
Странно. У меня первый код скомпилировался...
grizlik78
Эксперт С++
1908 / 1440 / 111
Регистрация: 29.05.2011
Сообщений: 2,996
05.06.2011, 23:28 #4
Ну вот g++ 4.5.1 артачится чего-то.
silent_1991
Эксперт С++
4963 / 3039 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
05.06.2011, 23:31 #5
Хаа, действительно, g++ не нравится этот код, а майкрософт его спокойно глотает...
lemegeton
2923 / 1352 / 135
Регистрация: 29.11.2010
Сообщений: 2,725
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; // нормуль
  }
};
CyBOSSeR
Эксперт C++
2300 / 1670 / 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 имена не ищутся в базовых шаблонных классах ни при определении класса ни при его инстанцировании, что собственно наблюдается в данном случае.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.06.2011, 11:02
Привет! Вот еще темы с ответами:

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

Правда, что указатель класса-наследника не может указывать на объект класса-родителя? - C++
Доброго времени суток! Пример кода ниже. Правда ли , что указатель класса-наследника не может указывать на объект класса-родителя? ...

Как сделать, чтобы функция класса могла работать с обьектами другого класса - C++
есть класс к примеру class One и класс к примеру class Two нужно чтобы элемент функция класса One могла работать в обьектами класа...

Может ли метод класса возвращать экземпляр этого же класса? - C++
такой вопрос, реально что бы функция класса имела тип класса(возвращала класс), то есть типа так: class c1{ c1 f1(); } если да, то...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
06.06.2011, 11:02
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru