Почему одна функция работает только в пределах другой функци наследованого класа?

Почему если я визиваю в наследуваном класе функцию set в области класа наследования видает ошибку а елсли в областе функции наследованого класа все работает? Ведь если базовый класс наследуется как защищенный, все открытые и защищенные члены базового класса становятся защищенными членами производного класса. Но когда я визиваю public член базового класа внутри производного класа то видает ошибку? Почему так?

class B {
protected:
int i, j;

public:

void set(int a, int b) {
    i = a; j = b;
}

void show() {
    cout << i << "\t" << j<<endl;
}

int ko;
};


class D :protected B {
int k;

public:
//  set(4, 2); ПОЧЕМУ ЗДЕСЬ ВИДАЕТ ОШИБКУ 
void setk() { 
//set(5,3); А ЕСЛИ ЗДЕСЬ ВИЗОВ БУДЕТ ТО ВСЬО НОРМАЛЬНО ПОЧЕМУ ТАК?
k = i * j;
}
void showk() { cout <<"k"<< k << endl; }
};

Ответы (1 шт):

Автор решения: VladimirS

Функции и методы можно вызывать только из функций и методов.

Ещё проще: вся программа (причём любая, на любом языке программирования написанная), представляет собой набор описаний - объявлений (declaration) и определений (definition), которые описывают любые пользовательские данные как совокупность других данных, а в конечном счёте - машинных данных (по принципу, "от простого к сложному"), а любые операции/процедуры/функции/методы - как совокупность других операций/процедур/функций/методов, в конечном счёте тех, которые присущи данной машине (тоже, по принципу, "от простого к сложному"). Поскольку любая программа на любом ЯП - набор описаний - ответов на вопросы "что", "как" и "с чем" делать предназначенная для формального (бездумного) исполнения вычислительной машиной, то она имеет ряд правил формальной записи - синтаксис, на основе которого, "бездумная железяка" сводит её к форме, содержащей исключительно операции конкретной "бездумной железки", что позволяет ей ("бездушной машине") выполнить "скормленный" ей "рецепт" - программу.

Синтаксис Си-подобных языков программирования (в число которых входит C++), не определяет, как следует интерпретировать вызов функции/метода/операции осуществляемый извне тела (того, что меж фигурных скобочек) другой функции/метода/операции. Именно поэтому, алгоритм работы компилятора не предусматривает каких-либо действий в случае обнаружения такой записи как у Вас.

В принципе, в любой непонятной ситуации, компилятор/интерпретатор может (гипотетически) сделать одну из четырёх вещей:

  1. Забить (просто пропустить непонятный участок кода)
  2. Забить и выдать сообщение о том, что обнаружена какая-то запись, которую неизвестно как интерпретировать. Например - выдать предупреждение (Warning).
  3. Обратить внимание и попросить пользователя (программиста) самому выбрать, что делать с непонятным участком кода.
  4. Поставить пользователя (программиста) перед фактом, что обнаружена запись, алгоритм интерпретации которой не определён - сообщить, что это - ошибка и остановить работу.

Именно 4й вариант и выбран разработчиками компилятора C++, видимо, по соображениям, что если что-то написано, то оно написано зачем-то, а если что-то неясно как интерпретировать, но оно написано зачем-то, то это ошибка, т.к. любая запись, которая зачем-то сделана, но алгоритм интерпретации которой не определён, наверняка является ошибкой.

→ Ссылка