С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.73/11: Рейтинг темы: голосов - 11, средняя оценка - 4.73
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,705

базовый и производный класс, в базовом объявлена переменная "protected", она недоступна по имени в производном классе! template <class T> воду мутит!

12.06.2011, 22:52. Показов 2492. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Друзья! Вот код

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
25
26
27
#include <stdio.h>
template <class T>
class otets {
 protected:
  int peremennaya;
};
 
template <class T>
class sinn: public otets<T> {
 void  f ();  
};
 
template <class T>
void sinn<T>::f () {
 otets<T>::peremennaya= 11;
 sinn<T>::peremennaya= 11;
 //peremennaya= 11;
}
 
int main() {
 sinn<int> h;
 printf ("%x\n", &h.otets<int>::peremennaya);
 printf ("%x\n", &h.sinn<int>::peremennaya);
 printf ("%x\n", &h.peremennaya);
 getchar ();
}
{}
Вот какое-то несерьёзное поведение компилятора g++; все знают, что поля protected базового класса наследуются производными, а значит, в классе sinn просто-таки ОБЯЗАНА присутствуовать переменная peremennaya, но её там нет! Нет её и всё, ибо

C++
1
peremennaya= 11;
Приводит к ошибке. Зато

C++
1
2
 otets<T>::peremennaya= 11;
 sinn<T>::peremennaya= 11;
компилится, в то время, как всё вот это:
otets<int>:eremennaya;
sinn<int>:eremennaya;
peremennaya;

НАходится ПО ОДНОМУ адресу, а значит, логично просто квалифицировать это поле как
peremennaya;

Не получается. Почему?

++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++

Блин, MSVC без проблем компилит;
C++
1
2
3
otets<T>::peremennaya= 11;
 sinn<T>::peremennaya= 11;
peremennaya= 11;
придётся, наверное, прогнуться под g++ и не писать:

C++
1
peremennaya= 11;
, я разачаровываюсь в g++


Ну и сразу вопрос, как грамотнее будет писать для компиляторосовместимости:
C++
1
2
3
4
template <class T>
void sinn<T>::f () {
 otets<T>::peremennaya= 11;
}
или

C++
1
2
3
4
template <class T>
void sinn<T>::f () {
  sinn<T>::peremennaya= 11;
}
, имея ввиду, что это суть одно и то же? Спасибо

Добавлено через 17 минут
Вообще вся эта катавасия опять определяется template <class T>! Уибраем сие и всё компилится нормально!
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
class otets {
 public:
  int peremennaya;
};
 
class sinn: public otets {
 void  f ();  
};
 
void sinn::f () {
 otets::peremennaya= 11;
 sinn::peremennaya= 11;
 peremennaya= 11;
};
 
int main() {
 sinn h;
 printf ("%x\n", &h.otets::peremennaya);
 printf ("%x\n", &h.sinn::peremennaya);
 printf ("%x\n", &h.peremennaya);
 getchar ();
}
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
12.06.2011, 22:52
Ответы с готовыми решениями:

Есть базовый и производный класс, в базовом определена функция, необходимо её объявить в производном!
Как-то так, что ли: class x { public: void f_0 (){}; }; class y: public x { public: //Тут у меня пойдёт...

Указатели в базовом классе на базовый класс и производный класс
Пишу контейнер &quot;Бинарное дерево поиска&quot; для частотного словаря. С самим контейнером особо вопросов нету. Вопрос по поводу элементов в...

Необходимо по инстанциировать производный класс по имени и запустить метод описанный в его базовом классе.
Есть несколько классов, наследованных от класса Parent. класс Parent содержит метод writeData. Производные классы его не переопределяют....

9
Эксперт С++
 Аватар для schdub
3073 / 1411 / 425
Регистрация: 19.01.2009
Сообщений: 3,893
13.06.2011, 01:06
Цитата Сообщение от kravam Посмотреть сообщение
Ну и сразу вопрос, как грамотнее будет писать для компиляторосовместимости
C++
1
2
3
// ...
this->peremennay = 11;
// ...
Это происходит из-за особенности разрешения неквалифицированных имен внутри шаблонов. Согласно стандарту, компилятор обязан производить поиск там где объявлен или определен шаблон, причем в зависимых базовых классах, поиск не производится.

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
25
26
27
28
29
30
31
32
33
#include <iostream>
 
template <class T> class Base {
protected:
    int foo;
public:
    Base() {
        std::cout << "Base::foo address = " << & this->foo << std::endl;
    }
};
 
template <class T> class Derived : public Base<T> {
public:
    Derived() {
        std::cout << "Derived::foo address = " << & this->foo << std::endl;
    }
 
    void  bar (int value);
};
 
template <class T> void Derived<T>::bar (int value) {
    this->foo = value;
    std::cout << std::endl
        << "Base<T>::foo value " << Base<T>::foo << std::endl
        << "Derived<T>::foo value " << Derived<T>::foo << std::endl
        << "this->foo value " << this->foo << std::endl;
}
 
int main() {
    Derived<int> h;
    h.bar(666);
    return 0;
}
Code
1
2
3
4
5
6
7
8
9
10
oleg@oleg-laptop:~$ cd src/tmp
oleg@oleg-laptop:~/src/tmp$ g++ main.cpp
oleg@oleg-laptop:~/src/tmp$ ./a.out
Base::foo address = 0xbfb82220
Derived::foo address = 0xbfb82220
 
Base<T>::foo value 666
Derived<T>::foo value 666
this->foo value 666
oleg@oleg-laptop:~/src/tmp$
1
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,705
13.06.2011, 02:25  [ТС]
schdub, тут не ошибка?
причем в зависимых базовых классах, поиск не производится.
0
Эксперт С++
 Аватар для schdub
3073 / 1411 / 425
Регистрация: 19.01.2009
Сообщений: 3,893
13.06.2011, 13:36
Цитата Сообщение от kravam Посмотреть сообщение
schdub, тут не ошибка?
нет.

вот классический пример:
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
25
26
#include <iostream>
 
int foo;
 
template <typename T> class Base {
public:
    int foo;
};
 
template <typename T> class Derived : public Base<T> {
public:
    int get_foo () const {
        return foo;
    }
};
 
int main() {
 
    foo = 666;
 
    Derived<int> h;
    h.foo = 999;
 
    std::cout << h.get_foo() << std::endl;
    return 0;
}
Программа напечатает значение переменной foo из глобальной области видимости.


теперь меняем реализацию get_foo() на:
C++
1
2
3
    int get_foo () const {
        return this->foo;
    }
И в выводе получаем то что ожидали .
0
 Аватар для OstapBender
594 / 532 / 76
Регистрация: 22.03.2011
Сообщений: 1,585
13.06.2011, 13:40
у меня в обоих случаях выводит 999
0
Эксперт С++
 Аватар для schdub
3073 / 1411 / 425
Регистрация: 19.01.2009
Сообщений: 3,893
13.06.2011, 13:43
Цитата Сообщение от OstapBender Посмотреть сообщение
у меня в обоих случаях выводит 999
Компилятор? Мы обсуждаем g++.
0
 Аватар для OstapBender
594 / 532 / 76
Регистрация: 22.03.2011
Сообщений: 1,585
13.06.2011, 13:47
sry guys
0
Эксперт С++
 Аватар для schdub
3073 / 1411 / 425
Регистрация: 19.01.2009
Сообщений: 3,893
13.06.2011, 13:58
Более подробно об этом аспекте можно почитать, например, у Александреску и Саттера в их книге "Стандарты программирования на С++" стр. 138 (начиная с последнего абзаца).
C++ Coding Standarts
Избегайте зависимости от зависимых имен. Говоря неформально, зависимое имя — это имя, которое каким-то образом упоминает параметр шаблона. Многие компиляторы не поддерживают "двухфазный поиск" для зависимых имен из стандарта C++, а это означает, что код шаблона, использующий зависимые имена, будет вести себя по-разному на разных компиляторах, если только не принять меры для полной определенности при использовании зависимых имен. В частности, особого внимания требует наличие зависимых базовых классов, когда шаблон класса наследуется от одного из параметров этого шаблона (например, Т в случае template<typename T>class C:T{} или от типа, который построен с использованием одного из параметров шаблона (например, Х<Т> в случае template<typename T>class C:X<T>{}.

Коротко говоря, при обращении к любому члену зависимого базового класса необходимо всегда явно квалифицировать имя с использованием имени базового класса или при помощи this->. Этот способ можно рассматривать просто как некую магию, которая заставляет все компиляторы делать именно то, что вы от них хотите.

C++
1
2
3
4
5
6
7
8
9
10
11
12
template<typename T>
class С : Х<Т> {
    typename Х<Т>::SomeType s;  // использование вложенного
                                // типа (или синонима
                                // typedef) из базового
                                // класса
public:
    void f() {
        X<T>::baz();            // Вызов функции-члена
                                // базового класса
        this->baz();            // Альтернативный способ
};
2
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,705
13.06.2011, 20:55  [ТС]
schdub, я хотел узнать а ОТ ЧЕГО ЗАВИСИТ базовый класс, почему и переспросил.
Просто производный зависит от базового. А базовый от чего?
0
Эксперт С++
 Аватар для schdub
3073 / 1411 / 425
Регистрация: 19.01.2009
Сообщений: 3,893
13.06.2011, 22:05
Он зависит от параметра шаблона.

Подробнее можно почитать у Ray Lischner - С++ In a Nutshell (7.8.1 Зависимые имена)

Или в стандарте у мну только n1905 Working Draft
14.6.2 Dependent names
Inside a template, some constructs have semantics which may differ from one instantiation to another. Such a construct depends on the template parameters. In particular, types and expressions may depend on the type and/or value of template parameters (as determined by the template arguments) and this determines the context for name lookup for certain names. Expressions may be type-dependent (on the type of a template parameter) or value-dependent (on the value of a non-type template parameter).
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
13.06.2011, 22:05
Помогаю со студенческими работами здесь

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

Один и тот же метод объявлен в базовом private, а в производном public; и по ссылке на производный класс он не вызывается!
Прежде всего, вот код который компилится и работает, он описан у Эккеля (глава 8 &quot;Полиморфизм&quot;): import static...

Создание ссылки на производный класс в базовом классе
Доброго времени суток. Есть такой вопрос: &quot;Как обратиться к методам производного класса из базового?&quot; Если создать ссылку на...

Одна переменая в базовом и производном классе
Добрый день, есть как сделать одну переменную для базового класса и произвольного. Допустим мне нужно вызвать метод базового класса, а он...

Вызов события в производном классе, которое объявлено в базовом
Доброго времени суток, Господа. Возник вопрос. Есть класс A: public abstract class A { public event...


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru