TGStat
TGStat
Qidiruv uchun matnni kiriting
Ilg‘or kanal qidiruvi
  • flag Uzbek
    Sayt tili
    flag Russian flag English flag Uzbek
  • Saytga kirish
  • Katalog
    Kanal va guruhlar katalogi Hududiy to‘plamlar Tematik to‘plamlar Платные каналы Kanallar qidiruvi
    Kanal/guruh qo‘shish
  • Reytinglar
    Kanallar reytingi Guruhlar reytingi Postlar reytingi
    Brendlar va shaxslar reytingi
  • Analitika
  • Postlarda qidiruv
  • Telegram'ni kuzatish
  • Targ‘ibot
    Yandex Business orqali reklama Реклама в каналах через TGStat Agency Реклама на сайте TGStat.ru
Грокаем C++

5 Aug, 12:00

Telegram'da ochish Ulashish Shikoyat qilish

​​Ответ
#опытным

2 вещи нужно знать(помимо всего остального С++😆), чтобы правильно ответить на квиз выше:

1️⃣ Сокрытие имен

Когда в классе объявляют метод с неким именем, все методы с этим именем из базовых классов становятся невидимыми (скрытыми), независимо от их параметров.

То есть

struct A {
void func(const std::string&);
};

struct B : A {
void func(float);
};

B b;

у объекта b можно вызвать только флотовый вариант func.

Почему так?

Компилятор увидел вызов метода и должен выполнить overload resolution. Он видит, что у объекта b статический тип B и идет смотреть, какие методы из этого класса подходят для вызова.

И вот здесь срабатывает ключевая особенность поиска. Компилятор ищет имя func по цепочке областей видимости — снизу вверх (от производного класса к базовому). Как только он находит хотя бы одно объявление с именем func, поиск по иерархии немедленно останавливается . Дальше вверх (в A) он уже не заглядывает.

В классе B есть func(float) — имя найдено. Поиск завершён. В набор кандидатов для overload resolution попадает только B::func(float). Метод A::func(const std::string&) в этот набор даже не рассматривается — он остался за границей поиска.

Поэтому:

b.func(15.f); // OK: float
b.func("hello"); // Compile Error

2️⃣ Вообще говоря, это сокрытие имен - это проблема с точки зрения привычного нам ООП.

"У меня есть базовый класс, от которого я наследую функциональность. Почему я не могу использовать метод базового класса?"

Сокрытие имен - процесс неявный. Но мы можем явно сказать, какой сокрытый метод мы как разработчики хотим видеть в наследнике.

С помощью директивы using можно вернуть видимость методу базового класса в наследник:

struct A {
void func(const std::string&);
};

struct B : A {
using A::func;
void func(float);
};

B b;
b.func(15.f); // OK
b.func("hello"); // OK

using A::func; позволяет компилятору увидеть метод, принимающий строку, и успешно вызывать его при передаче строкового литерала.

Такой же прием кстати используется в реализации overloaded паттерна.

Когда мы это знаем, правильные ответы находятся на поверхности:

struct A {
void func(const std::string&); // #1
};

struct B : A {
void func(float); // #2
};

struct C : B {
using A::func;
void func(int); // #3
};

C c;
B& b = c;

c.func(3.14f); // вызывает #3 за счет неявного приведения float к int

c.func(123); // вызывает #3

c.func("hello"); // вызывает #1 за счет using

b.func(3.14f); // вызывает #2

Don't let others shadow you. Stay cool

#cppcore

3k 0 23 20 58
Katalog
Kanal va guruhlar katalogi Kanallar to‘plamlari Kanallar qidiruvi Kanal/guruh qo‘shish
Reytinglar
Telegram-kanallar reytingi Telegram-guruhlar reytingi Postlar reytingi Brendlar va shaxslar reytingi
API
Statistika API'si Postlar qidiruvi API'si API Callback
Kanallarimiz
@TGStat @TGStat_Chat @telepulse @TGStatAPI
O‘qish
Академия TGStat Telegram tadqiqoti 2019 Telegram tadqiqoti 2021 Telegram tadqiqoti 2023
Kontaktlar
Справочный центр Qo‘llab-quvvatlash Email Vakansiyalar
Har xil narsalar
Foydalanuvchi shartnomasi Maxfiylik siyosati Ommaviy oferta
Botlarimiz
@TGStat_Bot @SearcheeBot @TGAlertsBot @tg_analytics_bot @TGStatChatBot