Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.192] |
|
|
Правила раздела:
| Страницы: (495) « Первая ... 58 59 [60] 61 62 ... 494 495 ( Перейти к последнему сообщению ) |
Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
|
Сообщ.
#886
,
|
|
|
|
Какая польза от конструкций, позволяющих писать грамотный код и формализовывать гарантии? Наверное - они только мешают, ога
|
|
Сообщ.
#887
,
|
|
|
|
Цитата D_KEY @ Это как спецификации исключений. Вот мне, например, нравится проверяемые исключения в Java. плюсую, очень понравилось сообщение IDEA а ля "вот этот метод может выбросить такие-то исключения, обработай-ка", вот только не помню, отказывается ли компилер компилить, если не обработать исключения. если да, то это несколько увеличивает связность между модулями. |
|
Сообщ.
#888
,
|
|
|
|
Цитата DesweR @ Цитата D_KEY @ Как минимум также. В какой-то конкретной ситуации возможны какие-то улучшения концепции. В любом случае, const тут только поможет явно указать контракты. А если для другого клиента необходим доступ методу, который значится константным? Что делать с const? Вообще его убирать? Поясни. Не понял. Если метод значится константным и открытым, то его могут использовать все клиенты. Добавлено Дополнительные контракты, самодокументируемость и дополнительный контроль типов во время компиляции. |
|
Сообщ.
#889
,
|
|
|
|
Цитата D_KEY @ Поясни. Не понял. Пояснять нечего: не понял он, что такое const |
|
Сообщ.
#890
,
|
|
|
|
Цитата korvin @ Цитата D_KEY @ Это как спецификации исключений. Вот мне, например, нравится проверяемые исключения в Java. плюсую, очень понравилось сообщение IDEA а ля "вот этот метод может выбросить такие-то исключения, обработай-ка", вот только не помню, отказывается ли компилер компилить, если не обработать исключения. если да, то это несколько увеличивает связность между модулями. Отказывается. Связность-то как это увеличивает? У некой подсистемы есть иерархия ошибок. Кроме того, не проверяются runtime-исключения(не помню названия базового класса). |
|
Сообщ.
#891
,
|
|
|
|
Цитата D_KEY @ Кроме того, не проверяются runtime-исключения В том числе нехватка памяти, что для плюсов неприемлемо ![]() Но, вообще, да, обоими руками да ещё и ногами в придачу за статическую проверку спецификации исключений. |
|
Сообщ.
#892
,
|
|
|
|
Цитата Повстанець @ Дурачка включил? Занафиг мне дополнительный этап наследования от каких либо интерфейсов, если я могу просто const поставить? Тем более бОльшая часть используемых классов обычно даже не твоего авторства. Что с ними делать? Дополнительно наследоваться? Зачем? И каким образом ты подставишь const к методам чужого класса без его наследования/изменения? Цитата Повстанець @ ![]() ![]() class some_class_a { public: virtual int get_x() = 0; virtual int get_y() = 0; virtual void set_x(int) = 0; virtual void set_y(int) = 0; }; class read_only : virtual public some_class_a { private: using some_class_a::set_x; using some_class_a::set_y; }; class only_y : virtual public some_class_a { private: using some_class_a::set_x; using some_class_a::get_x; }; class some_class : public read_only, public only_y { //... }; void read_only_f(read_only& ro) { //... } void only_y_f(only_y& oy) { //... } some_class sc; read_only_f(sc); only_y_f(oy); Мдааа, Целых четыре класса(!), один из которых обязательный базовый, два других - псевдо-интерфейсы, наследующие "по привычке" все методы базового класса, из которых "лишние" методы приходится самому ручками прятать через понижение их видимости(!). Цитата D_KEY @ Поясни. Не понял. Если метод значится константным и открытым, то его могут использовать все клиенты. Разграничение доступа, один клиент должен иметь доступ к конкретному методу, а другой клиент не должен иметь доступа. Цитата D_KEY @ Дополнительные контракты, самодокументируемость и дополнительный контроль типов во время компиляции. Для тривиальных задач в принципе неплохо. |
|
Сообщ.
#893
,
|
|
|
|
Цитата MyNameIsIgor @ Но, вообще, да, обоими руками да ещё и ногами в придачу за статическую проверку спецификации исключений. Голосовал? |
|
Сообщ.
#894
,
|
|
|
|
Цитата D_KEY @ Голосовал? Да, но не |
|
Сообщ.
#895
,
|
|
|
|
Цитата DesweR @ Мдааа, ![]() Такое же, как и у тебя Один в один же. Цитата Ну а причем тут вообще const?Цитата D_KEY @ Поясни. Не понял. Если метод значится константным и открытым, то его могут использовать все клиенты. Разграничение доступа, один клиент должен иметь доступ к конкретному методу, а другой клиент не должен иметь доступа. Через интерфейсы(у нас - через абстрактные классы), конечно. Причем это никак не отменяет const. Цитата Цитата D_KEY @ Дополнительные контракты, самодокументируемость и дополнительный контроль типов во время компиляции. Для тривиальных задач в принципе неплохо. Причем тут решение задач и их сложность ? Я же все вроде объяснил. Добавлено Цитата MyNameIsIgor @ Цитата D_KEY @ Голосовал? Да, но не ![]() Кстати, я честно говоря, рассчитывал на больший интерес к теме, а выяснилось, что многие даже не слышали про проверяемые исключения... Профита мало было с той темы... |
|
Сообщ.
#896
,
|
|
|
|
Цитата D_KEY @ Такое же, как и у тебя Один в один же. Чего?! Да разница, как между небом и землёй, покажи хоть одно совпадение. Цитата D_KEY @ Ну а причем тут вообще const? При том, что когда задача разрастается из тривиальной - const становится неприменим. Добавлено Цитата D_KEY @ Кстати, я честно говоря, рассчитывал на больший интерес к теме, а выяснилось, что многие даже не слышали про проверяемые исключения... Профита мало было с той темы... Всё новое - это хорошо откопанное старое |
|
Сообщ.
#897
,
|
|
|
|
Цитата DesweR @ Во всех приличных библиотеках он там уже стоит.И каким образом ты подставишь const к методам чужого класса без его наследования/изменения? Цитата DesweR @ Какая задача, такое и решение. От твоего принципиально ничем не отличается. Мдааа, ну и гов тихий ужас Добавлено Цитата DesweR @ Мужики то и не знали... При том, что когда задача разрастается из тривиальной - const становится неприменим. |
|
Сообщ.
#898
,
|
|
|
|
Цитата DesweR @ Цитата D_KEY @ Такое же, как и у тебя Один в один же. Чего?! Да разница, как между небом и землёй, покажи хоть одно совпадение. Назови хоть одно отличие Цитата Цитата D_KEY @ Ну а причем тут вообще const? При том, что когда задача разрастается из тривиальной - const становится неприменим. То есть мне его удалить сейчас из всех своих проектов? Добавлено Цитата DesweR @ Есть класс с несколькими полями, экземпляр этого класса нужно передать одному клиенту с доступом к полям "read only", а другому клиенту с возможностью полного доступа, но только к одному полю. А этого не достаточно? ![]() ![]() class ISomeClass { public: virtual void SetY(int y) = 0; protected: ~ISomeClass(); }; class TSomeClass : public ISomeClass { public: int GetX() const; void SetX(int x); int GetY() const; /*override*/ void SetY(int y); //... }; void client1(const TSomeClass &obj) { // не можем изменить состояние obj } void client2(ISomeClass &obj) { // можем вызывать только obj.SetY(some_value) } Добавлено Цитата DesweR @ А вот как в С++ разруливается такая ситуация? Есть класс с несколькими полями, экземпляр этого класса нужно передать одному клиенту с доступом к полям "read only", а другому клиенту с возможностью полного доступа, но только к одному полю. ![]() ![]() type ISomeClass1 = interface function GetX: Integer; function GetY: string; property X: Integer read GetX; property Y: string read GetY; end; ISomeClass2 = interface function GetY: string; procedure SetY(const AY: string); property Y: string read GetY write SetY; end; TSomeClass = class(TInterfacedObject, ISomeClass1, ISomeClass2) strict private function GetX: Integer; procedure SetX(const AX: Integer); function GetY: string; procedure SetY(const AY: string); public property X: Integer read GetX write SetX; property Y: string read GetY write SetY; end; function TSomeClass.GetX: Integer; begin // end; procedure TSomeClass.SetX(const AX: Integer); begin // end; function TSomeClass.GetY: string; begin // end; procedure TSomeClass.SetY(const AY: string); begin // end; procedure MyClient1(const SomeClass: ISomeClass1); var X: Integer; Y: string; begin X := SomeClass.X; //SomeClass.X := X; Cannot assign to a read-only property Y := SomeClass.Y; //SomeClass.Y := Y; Cannot assign to a read-only property end; procedure MyClient2(const SomeClass: ISomeClass2); var X: Integer; Y: string; begin //X := SomeClass.X; Undeclared identifier: 'X' //SomeClass.X := X; Undeclared identifier: 'X' Y := SomeClass.Y; SomeClass.Y := Y; end; ... var SomeClass: TSomeClass; X: Integer; Y: string; begin SomeClass := TSomeClass.Create; X := SomeClass.X; SomeClass.X := X; Y := SomeClass.Y; SomeClass.Y := Y; MyClient1(SomeClass); MyClient2(SomeClass); А что будет, если я случайно при реализации метода интерфейса для readonly поменяю значение внутреннего поля? |
|
Сообщ.
#899
,
|
|
|
|
DesweR, исключительно чтобы вы больше здесь не разорялись (хотя это вряд ли
)Для начала для прекращения всех оров о количестве классов вводим мегаконструкцию ![]() ![]() ![]() #define interface class Далее вот это ![]() ![]() ISomeClass1 = interface function GetX: Integer; function GetY: string; property X: Integer read GetX; property Y: string read GetY; end; меняем на ![]() ![]() interface read_only { read_only(const read_only&); const read_only& operator= (const read_only&); public: read_only() {} virtual int get_x() const = 0; virtual std::string get_y() const = 0; virtual ~read_only() {} }; Потом вот это ![]() ![]() ISomeClass2 = interface function GetY: string; procedure SetY(const AY: string); property Y: string read GetY write SetY; end; заменяем на это ![]() ![]() interface only_y { only_y(const only_y&); const only_y& operator= (const only_y&); public: only_y() {} virtual std::string get_y() const = 0; virtual void set_y(const std::string& s) = 0; virtual ~only_y() {} }; Мега класс ![]() ![]() ISomeClass2 = interface function GetY: string; procedure SetY(const AY: string); property Y: string read GetY write SetY; end; TSomeClass = class(TInterfacedObject, ISomeClass1, ISomeClass2) strict private function GetX: Integer; procedure SetX(const AX: Integer); function GetY: string; procedure SetY(const AY: string); public property X: Integer read GetX write SetX; property Y: string read GetY write SetY; end; function TSomeClass.GetX: Integer; begin // end; procedure TSomeClass.SetX(const AX: Integer); begin // end; function TSomeClass.GetY: string; begin // end; procedure TSomeClass.SetY(const AY: string); begin // end; становится ![]() ![]() class all: public read_only, public only_y { public: all() : s_("all"), x_(0) {} int get_x() const { return x_; } void set_x(int x) { x_ = x; } std::string get_y() const { return s_; } void set_y(const std::string& s) { s_ = s; } private: std::string s_; int x_; }; А привередливые клиенты ![]() ![]() procedure MyClient1(const SomeClass: ISomeClass1); var X: Integer; Y: string; begin X := SomeClass.X; //SomeClass.X := X; Cannot assign to a read-only property Y := SomeClass.Y; //SomeClass.Y := Y; Cannot assign to a read-only property end; procedure MyClient2(const SomeClass: ISomeClass2); var X: Integer; Y: string; begin //X := SomeClass.X; Undeclared identifier: 'X' //SomeClass.X := X; Undeclared identifier: 'X' Y := SomeClass.Y; SomeClass.Y := Y; end; превращаются в ![]() ![]() void want_read(read_only& ro) { std::cout << "X: " << ro.get_x() << " Y: " << ro.get_y() << std::endl; } void want_y(only_y& y) { std::cout << "before: " << y.get_y() << std::endl; y.set_y("want_y"); std::cout << "after: " << y.get_y() << std::endl; } Всё, запускаем ![]() ![]() int main() { all a; want_read(a); want_y(a); return 0; } Получаем ![]() ![]() X: 0 Y: all before: all after: want_y |
|
Сообщ.
#900
,
|
|
|
|
Боже мой... раздутые сахарные properties, мегатеоритики в типах и концепциях и впервыеслышащиеословоconst... 20 страниц...
QIP вроде на Дельфи писан. Наверно, брешут, слишком стабилен. |