Ошибки, баги, вопросы - страница 1055

 
zfs:
Сервисдеск в профиле своем найдите.
Благодарю!
 
A100:
Здесь нет противоречия, иначе B имел бы доступ к С.t как показано ниже, в то время как B не является производным C
В Вашем примере B должен иметь доступ к C.t и я не вижу причин это запрещать.
 
Zloy_Koldun:
В Вашем примере B должен иметь доступ к C.t и я не вижу причин это запрещать.

Странные вы оба.  Путаете классы и экземпляры.  По мне так и к t другого экземпяра того же класса B не должно быть доступа. 

Протектед поля должны быть доступны только собственные (этого же экземпляра B, т е. this), а другого экземпляра (даже того же класса B) - должны быть закрыты..  Вот давайте переименую для наглядности:

class Человек
{
protected:
   int кошелёк;
};
class Мужчина : public Человек
{
   int fч( Человек& ч );
   int fм( Мужчина& м );
};
int Мужчина::fч( Человек& ч )  // 1
{
   кошелёк = 100;       // Всё в порядке.  моё.
   int s =  ч.кошелёк;   // protected member access error  вполне справедливо
   return s;
}
int Мужчина::fм( Мужчина& м )  // 2
{
   кошелёк = 100;       // Всё в порядке, кошелёк мой собственный
   int s = м.кошелёк;   // это компилируется.  и это НЕПРАВИЛЬНО! кошелёк ЧУЖОЙ !!
// С фига ли я должен иметь доступ к твоему кошельку, только на основании того что мы с тобой оба "Мужчины" ?? 
   return s;
}

Т.е. по мне - обе функции не должны компилироваться, не только первая.  Если в С++ вторая компилируется и работает - то это прокол С++, а не достоинство.

Короче:

class Человек
{
protected:
   int кошелёк;
public:
   void Человек() {  a=3; }
   void gч( Человек& ч )
   {
    ч.кошелёк--;  // Даже это не должно компилироваться.  не следует лазить в чужой кошелёк!
    кошелёк++;    // в свой можно
   }   
};
 

Ваше сравнение с кошельком некорректно.

Я могу привести пример, где нужен доступ к  протектед членам, но дело не в моих или Ваших предпочтениях.

Если программист хочет что-то запретить, он может это сделать сам, а компилятор должен запрещать,

если это может нарушить работу программы.

В вышеприведённом примере, класс B знает о классе A, поэтому он ничего там не испортит.

А если хотите запретить, поместите его в секцию Private, или не наследуйтесь от одного класса, или придумайте тысячу других способов. 

 
MetaDriver:


Т.е. по мне - обе функции не должны компилироваться, не только первая.  Если в С++ вторая компилируется и работает - то это прокол С++, а не достоинство.

Тогда к своему кошельку тоже был бы запрещен доступ
Человек ч;
ч.gч( ч );
 
A100:
Тогда к своему кошельку тоже был бы запрещен доступ

Ещё раз:  тщательно различайте  классы (типы) и экземпляры (переменные).  Собственные (this) протектед поля - свободно доступны, в том числе при наследовании (в отличии от приватных), чужие (других переменных того же класса) не должны быть доступны. (должны быть недоступны)

Zloy_Koldun:
.....

В вышеприведённом примере, класс B знает о классе A, поэтому он ничего там не испортит.

...............

То что я знаю что у тебя есть кошелёк, не является основанием для доступа к нему.  К своему - пожалуйста.  К твоему - только через get() и set() - если ты разрешишь (public: int get();  int set();).

 
MetaDriver:


protected ограничивает доступ не на уровне объекта, а на уровне класса, потому что в момент компиляции не располагает сведениями об объектах. Я привел пример противоречия
Человек ч;
ч.gч( ч );
объект один и тот же
 
MetaDriver:

То что я знаю что у тебя есть кошелёк, не является основанием для доступа к нему.  К своему - пожалуйста.  К твоему - только через get() и set() - если ты разрешишь (public: int get();  int set();).

Кошелёк это всего лишь частный случай. И никто не мешает поместить его в приватную часть.

В другом случае может понадобиться доступ к переменной родительского класса чужого объекта.

И это должен программист решать, разрешать или нет. А компилятор должен обеспечить корректную работу программы. 

Документация по MQL5: Основы языка / Переменные
Документация по MQL5: Основы языка / Переменные
  • www.mql5.com
Основы языка / Переменные - Документация по MQL5
 
A100:
  Я привел пример противоречия ..  объект один и тот же

Противоречия нет. Если обращаешься к себе через "внешний интерфейс" - будь готов получить по морде от самого себя.  ;)

..........., потому что в момент компиляции не располагает сведениями об объектах.

 
Zloy_Koldun:

1. Кошелёк это всего лишь частный случай. И никто не мешает поместить его в приватную часть.

2. В другом случае может понадобиться доступ к переменной родительского класса чужого объекта.

3. И это должен программист решать, разрешать или нет.

4. А компилятор должен обеспечить корректную работу программы. 

1. Помещение в приватную часть ничего не изменит в случае

class Человек
{
private:
   int кошелёк; 
public:
   void Человек() {  кошелёк=3; }
   void gч( Человек& ч )  
   { 
    ч.кошелёк--;   // сейчас работает.  а не должно ;)
   }
};

При наследовании изменит, это понятно.

2. Мало чего кому понадобится... основания имеются только при доступе к собственному экземпляру.

3. Ну так и пусть решает.  Корректно. ;)

4. Вот весь вопрос в том и состоит: что именно считать "корректной работой".