Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.156] |
|
|
Правила раздела:
| Страницы: (495) « Первая ... 149 150 [151] 152 153 ... 494 495 ( Перейти к последнему сообщению ) |
Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
|
Сообщ.
#2251
,
|
|
|
|
Цитата MyNameIsIgor @ Цитата D_KEY @ Ну вообще korvin хотел, чтобы иначе, как через a.x.set и a.x.get получить доступ к x было бы нельзя. Странно... По идее, если мы передаём куда-то ссылку/указатель на Proxy, то подразумевается, что экземпляр A существует. И потом, даже имею эту ссылку/указатель, мы всё равно ничего не можем сделать с x, кроме того, что сами разрешили. Тогда почему бы сразу не хранить в public поля типа Int ?Цитата Есть бредовая мысль, которая тебе не понравится ещё больше махинаций с private декларациями Надо подумать и почитать.Это(эстетическая сторона дела) уже не важно. Я пока вообще не знаю как это сделать. Ну то есть можно поиграться с временными объектами, но тогда не будет ошибок компиляции , и все это будет непрозрачно для клиента. |
|
Сообщ.
#2252
,
|
|
|
|
Цитата D_KEY @ Тогда почему бы сразу не хранить в public поля типа Int? Ну, сравни, что мы можем сделать, имея ссылку на Int, и что - имея ссылку на Proxy, если я уберу using Int::set. Цитата D_KEY @ Это(эстетическая сторона дела) уже не важно. Я пока вообще не знаю как это сделать. Ну то есть можно поиграться с временными объектами, но тогда не будет ошибок компиляции , и все это будет непрозрачно для клиента. Ну, да, временный объект умрёт и будет хз что во время исполнения... Я хотел зайти с другой стороны и сделать каст Proxy в Proxy& приватным. Но сейчас перечитал и вспомнил, что это такой тёмный угол плюсов, что там не только у разных компиляторов противоречия, а даже в самом Стандарте. |
|
Сообщ.
#2253
,
|
|
|
|
Цитата DesweR @ Тьфу ты, там тоже варнинг, я там не вникал, уже без пяти минут было - домой собирался. я не знаю че ты там мутишь, в нормальных системах никаких проблем =) : ![]() ![]() [ ~/Devel/C++ ] g++ -Wall -o fint fint.cpp [ ~/Devel/C++ ] ./fint x = 10, y = 15, z = 20 Добавлено я-таки в Racket сделал это! =) ![]() ![]() #lang racket (define-syntax-rule (hidden outer-name class init ...) (begin (define inner-name (new class init ...)) (define/public (outer-name message . params) (send-generic inner-name (make-generic class message) . params)))) (define Int (class object% (define x 0) (define/public (get) x) (define/public (set v) (set! x v)) (super-new))) (define A (class object% (hidden x Int) (hidden y Int) (hidden z Int) (super-new))) (define (test) (define a (new A)) (send a x 'set 10) (send a y 'set 15) (send a z 'set 20) (printf "x = ~a, y = ~a, z = ~a\n" (send a x 'get) (send a y 'get) (send a z 'get)) (with-handlers ((exn:fail? (lambda (e) (printf "~a\n" e)))) (define x (send a x)) (printf "shit"))) ![]() ![]() > (test) x = 10, y = 15, z = 20 #(struct:exn:fail:contract:arity procedure x method in A: expects at least 1 argument, given 0 #<continuation-mark-set>) простите за оффтоп =) |
|
Сообщ.
#2254
,
|
|
|
|
Цитата korvin @ я-таки в Racket сделал это! =) Можешь пояснить идею? И ты скажи, вариант Игоря тебя устраивает или все-таки возможность использовать поля отдельно от объекта тебя не устраивает? |
|
Сообщ.
#2255
,
|
|
|
|
Цитата D_KEY @ Можешь пояснить идею? И ты скажи, вариант Игоря тебя устраивает или все-таки возможность использовать поля отдельно от объекта тебя не устраивает? идея проста: именем hided-поля (outer-name) фактически именуется публичный метод класса A, который принимает на вход имя метода (и другие параметры) и пересылает этот метод внутреннему объекту с именем inner-name класса Int. т.е. в C++ бы этот вызов выглядел наверное примерно так: ![]() ![]() A.x("set", [10]); A.x("get"); вариант Игоря меня устраивает, я пробовал так: ![]() ![]() Int x = a.x; выдает ошибку: ![]() ![]() [ ~/Devel/C++ ] g++ -Wall -o fint fint.cpp fint.cpp: In function ‘int main()’: fint.cpp:36: error: ‘Int’ is an inaccessible base of ‘A::Proxy’ но я не совсем понял, как ты все-таки вытаскиваешь объект Добавлено пардоньте мой Английский, правильней наверное hidden, а не hided =) Добавлено Цитата korvin @ вариант Игоря меня устраивает ну и единственно, что обернуть бы это в шаблон (или может макрос =/), чтоб не описывать каждый раз прокси-класс вручную Добавлено Цитата korvin @ ![]() ![]() A.x("set", [10]); A.x("get"); конечно хотелось бы, чтобы выглядел по-нормальному, чтоб без магии получения метода по имени (для Racket это нормально, а для C++, имхо, -- магия), ну и + стат. проверка тогда бы была возможна со стороны компилятора |
|
Сообщ.
#2256
,
|
|
|
|
Цитата korvin @ A.x("set", [10]); A.x("get"); Т.е. если сделать в таком виде, тебя устроет? Добавлено Цитата DesweR @ конечно хотелось бы, чтобы выглядел по-нормальному, чтоб без магии получения метода по имени (для Racket это нормально, а для C++, имхо, -- магия), ну и + стат. проверка тогда бы была возможна со стороны компилятора А ну ясно. |
|
Сообщ.
#2257
,
|
|
|
|
Цитата korvin @ идея проста: именем hided-поля (outer-name) фактически именуется публичный метод класса A, который принимает на вход имя метода (и другие параметры) и пересылает этот метод внутреннему объекту с именем inner-name класса Int. т.е. в C++ бы этот вызов выглядел наверное примерно так: ![]() ![]() A.x("set", [10]); A.x("get"); Можно в плюсах подумать над указателем на метод, шаблонами с переменным числом аргументов Цитата вариант Игоря меня устраивает, я пробовал так: ![]() ![]() Int x = a.x; выдает ошибку: ![]() ![]() [ ~/Devel/C++ ] g++ -Wall -o fint fint.cpp fint.cpp: In function ‘int main()’: fint.cpp:36: error: ‘Int’ is an inaccessible base of ‘A::Proxy’ но я не совсем понял, как ты все-таки вытаскиваешь объект Этот код не работает, потому что от Int Proxy унаследован закрыто. Если ты вместо Int поставишь A::Proxy(точнее ссылку на него), то тоже не сработает, но уже потому, что Proxy объявлен как private. Но в шаблон ты ссылку на A::Proxy передать передать можешь: ![]() ![]() template<typename T, typename DataT> T &assign(T &ref, const DataT &value) { ref.set(value); return ref; } ... int main() { A a; a.x.set(10); a.y.set(15); a.z.set(20); std::cout << "x=" << a.x.get() << " y=" << a.y.get() << " z=" << a.z.get() << std::endl; assign(a.x, 111); assign(a.y, 222); assign(a.z, 333); std::cout << "x=" << a.x.get() << " y=" << a.y.get() << " z=" << a.z.get() << std::endl; } Но если тебя устраивает, то и слава богу, - не нужно ломать голову над хаками |
|
Сообщ.
#2258
,
|
|
|
|
Цитата DesweR @ Т.е. если сделать в таком виде, тебя устроет? попробуй при этом сделать, чтобы внутренний объект и публичный метод с его именем объявлялись одной конструкцией типа ![]() ![]() type ... A = class hidden x :Int; end; тогда как минимум один из вариантов засчитаю. ну и вообще ты предлагай вариант, а там посмотрим, лишним не будет (это и к С++-никам относится) |
|
Сообщ.
#2259
,
|
|
|
|
korvin, мне бы все-таки хотелось услышать о практическом применении такого механизма
|
|
Сообщ.
#2260
,
|
|
|
|
Цитата D_KEY @ Но если тебя устраивает, то и слава богу, - не нужно ломать голову над хаками ![]() ну ассерты -- фиг с ними, но через шаблон что, получается таки можно получить ссылку на объект a.x и потом передать ее какому-нибудь другому объекту и он с ней сможет работать? |
|
Сообщ.
#2261
,
|
|
|
|
Цитата korvin @ Цитата D_KEY @ Но если тебя устраивает, то и слава богу, - не нужно ломать голову над хаками ![]() ну ассерты -- фиг с ними, но через шаблон что, получается таки можно получить ссылку на объект a.x и потом передать ее какому-нибудь другому объекту и он с ней сможет работать? Да, если не будешь явно указывать тип A::Proxy Добавлено Хуже того, работает и через auto ![]() ![]() auto &hack = a.x; hack.set(111); |
|
Сообщ.
#2262
,
|
|
|
|
Цитата D_KEY @ korvin, мне бы все-таки хотелось услышать о практическом применении такого механизма ![]() ну я ж сказал, что нехочу, чтоб ссылка на a.x могла храниться еще в каком-нить объекте. в случае языка с GC это означает, что b.x будет жить даже после того, как a умер (тоже самое в случае использования всяких умных указателей в C++), в случае же если a.x уничтожиться с a, то в b.x получаем невалидную ссылку => b перед обращением к b.x вынужден будет каждый раз проверять его на валидность. ну и чисто логически я не хочу, чтобы кто-то где-то обращался к части объекта. каких-то сверхсуперских бонусов это вроде не несет (либо я сам их тоже не знаю =) ) |
|
Сообщ.
#2263
,
|
|
|
|
Цитата korvin @ но через шаблон что, получается таки можно получить ссылку на объект a.x и потом передать ее какому-нибудь другому объекту и он с ней сможет работать? Да, как с Proxy, а не как с Int. Т.е. будет разрешено только то, что разрешили мы. |
|
Сообщ.
#2264
,
|
|
|
|
Цитата korvin @ Цитата D_KEY @ korvin, мне бы все-таки хотелось услышать о практическом применении такого механизма ![]() ну я ж сказал, что нехочу, чтоб ссылка на a.x могла храниться еще в каком-нить объекте. в случае языка с GC это означает, что b.x будет жить даже после того, как a умер (тоже самое в случае использования всяких умных указателей в C++), в случае же если a.x уничтожиться с a, то в b.x получаем невалидную ссылку => b перед обращением к b.x вынужден будет каждый раз проверять его на валидность. ну и чисто логически я не хочу, чтобы кто-то где-то обращался к части объекта. каких-то сверхсуперских бонусов это вроде не несет (либо я сам их тоже не знаю =) ) Хм. А может просто нужно возвращать мягкую ссылку? |
|
Сообщ.
#2265
,
|
|
|
|
Цитата D_KEY @ Хм. А может просто нужно возвращать мягкую ссылку? я плохо знаком с разными видами ссылок в C++, какого тогда будет поведение b.x, где b.x = a.x? все-таки в примере Игоря мне нравится, что компилятор сообщает о том, что x = a.x делать нельзя (хотя как оказалось иногда можно, а с auto так вообще все выкрутасы становятся бессмысленными =) ) |