Начну "издалека".
С C++. Где оператора with - нет (и слава богу - не будет).
( Зато есть "блочные переменные" и конструкции вида int & X = MyClass.MyField.MySubField; )
Пусть есть код:
-- в итоге код НЕ СКОМПИЛИРУЕТСЯ.
А как скомпилируется?
А вот так:
-- и эта стратегия компилятора - ПРАВИЛЬНАЯ.
Ведь если бы код компилировался, то что бы мы бы могли получить?
А вот что:
-- и мы получаем "неожиданные результаты".
Но! Компилятор так не делает.
Это и называется "обратная устойчивость".
А вот оператор with в Delphi "обратной устойчивостью" не обладает. А жаль.
Поясню:
-- а теперь так:
-- скажем так - ОГО!
Ну и...
На C++ как можно было бы написать?
-- понятно почему я написал про "переменные блока" и &? И почему "в этом контексте" языку C++ оператор with и не нужен.
С C++. Где оператора with - нет (и слава богу - не будет).
( Зато есть "блочные переменные" и конструкции вида int & X = MyClass.MyField.MySubField; )
Пусть есть код:
class A { private: int X; // - это приватный член класса A };//A int X = 0; // - это глобальная переменная class B : A { void Dummy () { X = 123; // - тут компилятор ОТРУГАЕТСЯ, скажет - "есть приватный член, // который может "затенять" глобальную переменную". }; };//B
-- в итоге код НЕ СКОМПИЛИРУЕТСЯ.
А как скомпилируется?
А вот так:
class A { private: int X; // - это приватный член класса A };//A int X = 0; // - это глобальная переменная class B : A { void Dummy () { ::X = 123; // - тут компилятор ругаться не будет, так как "поймёт", // что X - это ГЛОБАЛЬНАЯ переменная и ТОЛЬКО ОНА }; };//B
-- и эта стратегия компилятора - ПРАВИЛЬНАЯ.
Ведь если бы код компилировался, то что бы мы бы могли получить?
А вот что:
class A { protected: int X; // - это "защищённый" член класса A };//A int X = 0; // - это глобальная переменная class B : A { void Dummy () { X = 123; // - ОБА НА! тут X - "вдруг" стал членом класса A, // а не глобальной переменной }; };//B
-- и мы получаем "неожиданные результаты".
Но! Компилятор так не делает.
Это и называется "обратная устойчивость".
А вот оператор with в Delphi "обратной устойчивостью" не обладает. А жаль.
Поясню:
type TA = class public Caption : String; end;//TA TB = class public Caption : String; A : TA; end;//TB ... procedure TB.SomeProc; begin with A do Caption := '123'; // - это присвоится в Self.A.Caption end;
-- а теперь так:
Unit uA; ... type TA = class private Caption : String; end;//TA ... Unit uB; ... TB = class public Caption : String; A : TA; end;//TB ... procedure TB.SomeProc; begin with A do Caption := '123'; // - это присвоится в Self.Caption end;
-- скажем так - ОГО!
Ну и...
На C++ как можно было бы написать?
void TB::SomeProc () { ... { ... std::string & vCap = A.Caption; vCap = '123'; ... } ... }
-- понятно почему я написал про "переменные блока" и &? И почему "в этом контексте" языку C++ оператор with и не нужен.
> понятно почему я написал про "переменные блока" и &?
ОтветитьУдалитьНе совсем. =(
"Не совсем"
Удалитьint & X = A->B.->C->D->E;
...
X = 1234;
....
Y = X;
....
Z = X;
Вот теперь вообще ничего не понятно :). Что за Y и Z?
УдалитьЧто именно непонятно?
УдалитьY и Z - это "какие-то значения" совместимые с int & X.
На Delphi можно написать:
Удалитьwith A.B.C.D do
begin
...
x1 := SomeValue1;
x2 := SomeValue2;
end;
А на C++:
{
SomeData & X = A.B.C.D;
...
X.x1 := SomeValue1;
X.x2 := SomeValue2;
}
-- так понятно?
а если в первом примере class A вынести в отдельный модуль?
ОтветитьУдалить"а если в первом примере class A вынести в отдельный модуль?"
Удалить-- попробуете сами себе ответить на этот вопрос. Я лишь "задал вектор".