Re[12]: "class const - метод" - можно ли организовать?
От: _hum_ Беларусь  
Дата: 23.09.15 13:00
Оценка:
Здравствуйте, VTT, Вы писали:

VTT>Здравствуйте, _hum_, Вы писали:


__>>нет. и вы тоже не поняли значит. речь не о том, чтобы не модифицировать ЗАДАННЫЙ ЭКЗЕМПЛЯР, а о том, чтобы запретить модификацию ВСЕ ЭКЗЕМПЛЯРЫ, если код их модификации попадает "в нитку", которая запускается вызовом class_const-метода.


__>>иными словами компилятор должен действовать так:


__>>0) заводит стек функций

__>>1) помещает в стек class_const-метод
__>>2) пока стек не пуст, берет верхний элемент стека и для него анализирует тело функции:
__>> 2.1) все указатели типа C_A* трактует как const C_A* и выдает ошибку, если с помощью них производится попытка модификации;
__>> 2.2) если встретилась функция, то помещает в стек и переходит к 2);
__>> 2.3) делает pop для стека.
__>>3) анализ завершен

__>>(тут еще оговорки, конечно, для рекурсивных вызовов, но это тоже решаемо на этапе анализа — просто не надо добавлять в стек то, что уже раньше встречалось)


VTT>Запретить модификацию всех экземпляров можно в runtime — сделать в классе дополнительное статическое поле со счетчиком const обращений и кидать исключение, если при вызове не-const метода этот счетчик не 0.


неее, в рантайме это не дело.

VTT>А на этапе компиляции это сделать не получится, так как у компилятора может не быть реализации класса C_B (или это вообще голый интерфейс), и, соответственно, он не сможет определить наличие обращение к не-const экземплярам C_A в нем.


не совсем понял, в каком месте (и в какой ситуации) не пройдет описанный мною выше алгоритм?
Re: "class const - метод" - можно ли организовать?
От: B0FEE664  
Дата: 23.09.15 13:18
Оценка:
Здравствуйте, _hum_, Вы писали:

__>Потому встал вопрос, есть ли в других языках или в новом стандарте с++ что-нибудь наподобие "class const — метода", который делает

__>константными ЛЮБЫЕ this данного класса в своей области видимости, и тем самым предотвращает всякое изменение любого (а значит и заданного)объекта данного класса?

Может и есть, но в С++ это не возможно, так как можно взять указатель на память, где лежит данное, привести его void*, сериализовать в строку, передать в другую функцию, десерилизовать, разыменовать и изменить данное. Отследить данную цепочку в момент компиляции не возможно.

__>Это понадобилось, в частности, для того, чтобы на этапе компиляции отлавливать зацикливания.

Ловите зацикливания в рантайме: флажок и RAII — всё, что для этого нужно.
И каждый день — без права на ошибку...
Re[2]: "class const - метод" - можно ли организовать?
От: _hum_ Беларусь  
Дата: 23.09.15 13:26
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Здравствуйте, _hum_, Вы писали:


__>>Потому встал вопрос, есть ли в других языках или в новом стандарте с++ что-нибудь наподобие "class const — метода", который делает

__>>константными ЛЮБЫЕ this данного класса в своей области видимости, и тем самым предотвращает всякое изменение любого (а значит и заданного)объекта данного класса?

BFE>Может и есть, но в С++ это не возможно, так как можно взять указатель на память, где лежит данное, привести его void*, сериализовать в строку, передать в другую функцию, десерилизовать, разыменовать и изменить данное. Отследить данную цепочку в момент компиляции не возможно.


ну, с таким подходом, так и const-спецификаторы невозможны, и в вобще ничего невозможно, кроме двочиных числе в ячеках памяти. речь же о том, чтобы дать возможность отслеживать НЕПРЕДНАМЕРЕННУЮ модификацию.

__>>Это понадобилось, в частности, для того, чтобы на этапе компиляции отлавливать зацикливания.

BFE>Ловите зацикливания в рантайме: флажок и RAII — всё, что для этого нужно.

ага, особенно, если это система автопилота самолетом.
Re[3]: "class const - метод" - можно ли организовать?
От: B0FEE664  
Дата: 23.09.15 13:37
Оценка:
Здравствуйте, _hum_, Вы писали:

__>ага, особенно, если это система автопилота самолетом.


В системе автопилота самолета используется паттерн сигнал-слот? Не делайте так.
И каждый день — без права на ошибку...
Re[4]: "class const - метод" - можно ли организовать?
От: _hum_ Беларусь  
Дата: 23.09.15 14:22
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Здравствуйте, _hum_, Вы писали:


__>>ага, особенно, если это система автопилота самолетом.


BFE>В системе автопилота самолета используется паттерн сигнал-слот? Не делайте так.


во-первых, вы так сказали, не я;
во-вторых, чем вас не устраивает сигнал-слот архитектура?
ну, а в-третьих, речь шла про общую проблему гарантии немодифицируемости методом полей объекта (решение которой, в частности, позволило бы решить проблему отслеживания циклов на этапе написания кода).
Re[5]: "class const - метод" - можно ли организовать?
От: c-smile Канада http://terrainformatica.com
Дата: 23.09.15 15:39
Оценка:
Здравствуйте, _hum_, Вы писали:

__>во-вторых, чем вас не устраивает сигнал-слот архитектура?


Не устраивает двумя моментами:

1. Возможность возникновения event/signal loop. Невозможность доказать статически отсутсвие таких циклов.
2. Инфраструктура signal/slot занимает ресурсы. Как минимум память.

При условии наличия альтернативных механизмов свободных от 1 и 2 использование сигнал-слот представляется спорным.
Re[6]: "class const - метод" - можно ли организовать?
От: _hum_ Беларусь  
Дата: 23.09.15 15:49
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Здравствуйте, _hum_, Вы писали:


__>>во-вторых, чем вас не устраивает сигнал-слот архитектура?


CS>Не устраивает двумя моментами:


CS>1. Возможность возникновения event/signal loop. Невозможность доказать статически отсутсвие таких циклов.


так а разве этим не грешат любые варианты организации двунаправленной связи между объектами?

CS>2. Инфраструктура signal/slot занимает ресурсы. Как минимум память.


CS>При условии наличия альтернативных механизмов свободных от 1 и 2 использование сигнал-слот представляется спорным.


а можно узнать об альтернативных механизмах, которые бы преодолевали эти два пункта, при том же самом функционале?
Re[5]: "class const - метод" - можно ли организовать?
От: B0FEE664  
Дата: 23.09.15 16:59
Оценка:
Здравствуйте, _hum_, Вы писали:

__>>>ага, особенно, если это система автопилота самолетом.

BFE>>В системе автопилота самолета используется паттерн сигнал-слот? Не делайте так.
__>во-первых, вы так сказали, не я;
Я не предлагал использовать паттерн сигнал-слот для машин от которых может зависеть жизнь людей.
А что, собственно, я сказал? Я предложил добавить проверку времени исполнения. Проверка времени исполнения не может существенно замедлить код использующий сигнал-слот-архитектуру, так как на данный момент любая реализация этого патерна включает в себя приведение типа при каждом вызове слот-функции. А всякое такое приведение типа включает в себя проверку указателя на NULL во время приведения типа. Так что добавление проверки одного флажка не может существенно замедлить работу.

__>во-вторых, чем вас не устраивает сигнал-слот архитектура?

Тем, что сигнал-слот архитектура существенно повышает сложность понимания кода при одновременном снижении сложности разработки. Создаётся иллюзия, что эта архитектура упрощает код при фактическом его усложнении из-за динамического связывания вызовов функций. (Собственно то, что вам потребовалось такая хитрая проверка константности говорит именно об этом.) Упрощенно можно сказать, что эта архитектура приводит к тому, что вместо кода:
void f()
{
   fun1();
   fun2();
   fun3();
   fun4();
}

программист видит код:
void f()
{
   ...
}

где троеточие заменяется вызовами функций в самых произвольных местах проекта. Таким образом теряется локальность изменений и за изменениями становится сложно следить.
Если вы действительно хотите применить эту архитектуру для чего-то такого, от чего может зависеть жизнь людей, то вам жизненно необходимо вести документацию отображающую все деревья вызовов сигнал-слот.

__>ну, а в-третьих, речь шла про общую проблему гарантии немодифицируемости методом полей объекта (решение которой, в частности, позволило бы решить проблему отслеживания циклов на этапе написания кода).

Это ведь не единственная проблема данной архитектуры. Замените
    void C_B::foo_B(void){ m_pA->set_x(10);}

на
    void C_B::foo_B(void){ delete m_pA;}

и вы получите не менее эпический краш даже при гарантии немодифицируемости методом полей объекта.
И каждый день — без права на ошибку...
Re[13]: "class const - метод" - можно ли организовать?
От: VTT http://vtt.to
Дата: 23.09.15 17:12
Оценка:
Здравствуйте, _hum_, Вы писали:

0) заводит стек функций

__>не совсем понял, в каком месте (и в какой ситуации) не пройдет описанный мною выше алгоритм?


Да с самого начала. В общем случае у компилятора нет никакой возможности построить этот стек вызовов. Вот например: метод foo_B класса C_B вызывается через указатель на абстрактный базовый класс. О том, что вызвался метод именно в классе C_B мы можем узнать только в runtime.
Говорить дальше не было нужды. Как и все космонавты, капитан Нортон не испытывал особого доверия к явлениям, внешне слишком заманчивым.
Re[6]: "class const - метод" - можно ли организовать?
От: BulatZiganshin  
Дата: 23.09.15 18:15
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>где троеточие заменяется вызовами функций в самых произвольных местах проекта. Таким образом теряется локальность изменений и за изменениями становится сложно следить.


а по моему это типичный пример динамического связывания. с таким подходом, под подозрение должны попасть и виртуальные функции

а по сути дела такой подход позволяет внедрить что-то типа микросервисной архитектуры внутри одного приложения, когда одни модули предоставляю.т сервисы, другие их используют, и обе стороны работают соврешенно независимо, не пытаясь контролировать кто их вызывал или кого они вызвали "на другой стороне" шины
Люди, я люблю вас! Будьте бдительны!!!
Re[6]: "class const - метод" - можно ли организовать?
От: _hum_ Беларусь  
Дата: 23.09.15 19:30
Оценка:
Здравствуйте, B0FEE664, Вы писали:


BFE>А что, собственно, я сказал? Я предложил добавить проверку времени исполнения. Проверка времени исполнения не может существенно замедлить код использующий сигнал-слот-архитектуру, так как на данный момент любая реализация этого патерна включает в себя приведение типа при каждом вызове слот-функции. А всякое такое приведение типа включает в себя проверку указателя на NULL во время приведения типа. Так что добавление проверки одного флажка не может существенно замедлить работу.


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

__>>во-вторых, чем вас не устраивает сигнал-слот архитектура?

BFE>Тем, что сигнал-слот архитектура существенно повышает сложность понимания кода при одновременном снижении сложности разработки. Создаётся иллюзия, что эта архитектура упрощает код при фактическом его усложнении из-за динамического связывания вызовов функций. (Собственно то, что вам потребовалось такая хитрая проверка константности говорит именно об этом.) Упрощенно можно сказать, что эта архитектура приводит к тому, что вместо кода:
BFE>
BFE>void f()
BFE>{
BFE>   fun1();
BFE>   fun2();
BFE>   fun3();
BFE>   fun4();
BFE>}
BFE>

BFE>программист видит код:
BFE>
BFE>void f()
BFE>{
BFE>   ...
BFE>}
BFE>

BFE>где троеточие заменяется вызовами функций в самых произвольных местах проекта. Таким образом теряется локальность изменений и за изменениями становится сложно следить.
BFE>Если вы действительно хотите применить эту архитектуру для чего-то такого, от чего может зависеть жизнь людей, то вам жизненно необходимо вести документацию отображающую все деревья вызовов сигнал-слот.

погодите-погодите, кто говорил, что речь идет о динамическом связывании? во многих случаях (в том числе в моем) можно обойтись и статическим (никаких виртуальных функций, никаких observer-pattern, — обычная "магия шаблонов". см., например, библиотеку boost). но от этого проблема не пропадает (что указывает на ее общий характер).

__>>ну, а в-третьих, речь шла про общую проблему гарантии немодифицируемости методом полей объекта (решение которой, в частности, позволило бы решить проблему отслеживания циклов на этапе написания кода).

BFE>Это ведь не единственная проблема данной архитектуры. Замените
BFE>
BFE>    void C_B::foo_B(void){ m_pA->set_x(10);}
BFE>

BFE>на
BFE>
BFE>    void C_B::foo_B(void){ delete m_pA;}
BFE>

BFE>и вы получите не менее эпический краш даже при гарантии немодифицируемости методом полей объекта.

принципиальное отличие — вы можете и сами это проконтролировать (например, проверкой выполнения условия возможности удаления или использовать RAII). а вот отследить скрытые циклические зависимости, как в моем примере — это уже во многом неподъемная для программиста задача. потому и должен в этом случае приходить на помощь компилятор.
Re[14]: "class const - метод" - можно ли организовать?
От: _hum_ Беларусь  
Дата: 23.09.15 19:56
Оценка:
Здравствуйте, VTT, Вы писали:

VTT>Здравствуйте, _hum_, Вы писали:


VTT>0) заводит стек функций


__>>не совсем понял, в каком месте (и в какой ситуации) не пройдет описанный мною выше алгоритм?


VTT>Да с самого начала. В общем случае у компилятора нет никакой возможности построить этот стек вызовов. Вот например: метод foo_B класса C_B вызывается через указатель на абстрактный базовый класс. О том, что вызвался метод именно в классе C_B мы можем узнать только в runtime.


кхм.. извиняюсь, а как, по-вашему, компилятор генерирует код, если он не в курсе, кто что будет вызывать?
может, давайте все-таки на конкретном примере, и я вместо компилятора попробую вам пройтись по алгоритму?
если брать мой первоначальный пример, и считать, что там
void foo_A(void)class_const;

то компилятор будет действовать так:
— первый раз пробегает по тексту программы и заносит себе в память информацию о том, какие функции в программе объявлены (какие у них сигнатуры), и где у каждой объявленной функции определение (текст тела функции);
— второй раз пробегает по тексту программы и, встретив декларацию функции "foo_A(void)class_const", заносит ее первой в стек;
а дальше по п. 2)
берет с вершины стека foo_A(void)class_const и переходит к ее телу (информация о том, где оно , уже имеется после первого прохода):
void C_A::foo_A(void)const
{
    m_pB->foo_B();
}

в теле видит вызов функции void foo_B(void), потому заносит его сигнатуру в стек; и т.д.

в каком месте он может споткнуться?

upd. может, вы имели в виду виртуальные функции? ну, так о них пока речь не шла (там можно либо все проверять, либо договориться, что в таких случаях виртуальные использовать нельзя).
Отредактировано 23.09.2015 20:02 _hum_ . Предыдущая версия .
Re[15]: "class const - метод" - можно ли организовать?
От: VTT http://vtt.to
Дата: 23.09.15 20:38
Оценка:
Здравствуйте, _hum_, Вы писали:

__>кхм.. извиняюсь, а как, по-вашему, компилятор генерирует код, если он не в курсе, кто что будет вызывать?


Для компиляции ему вполне достаточно знать сигнатуру метода и откуда он берется (содержится в этом же исполняемом файле или импортируется).

__>- первый раз пробегает по тексту программы и заносит себе в память информацию о том, какие функции в программе объявлены (какие у них сигнатуры), и где у каждой объявленной функции определение (текст тела функции);


Дело в том, что как раз определения функции (текст тела функции) во время компиляции у компилятора может и не быть (я бы даже сказал что обычно нет).
Вот представьте, что класс C_B делает кто-то другой, а вам дает только заголовочный файл с объявлением этого класса и .dll (.lib) с его реализацией. А кода тела функции нет. И так со всеми системными и библиотечными функциями.
Даже если у вас есть код функции, он будет виден компилятору только если она inline или проект собирается с LTCG.

__>upd. может, вы имели в виду виртуальные функции? ну, так о них пока речь не шла (там можно либо все проверять, либо договориться, что в таких случаях виртуальные использовать нельзя).


Виртуальные я тоже имел ввиду. В начале вы вроде как упоминали сигнал-слоты, и на ум сразу приходит qt с его qobject и повальной виртуальностью.
Говорить дальше не было нужды. Как и все космонавты, капитан Нортон не испытывал особого доверия к явлениям, внешне слишком заманчивым.
Re[16]: "class const - метод" - можно ли организовать?
От: _hum_ Беларусь  
Дата: 23.09.15 21:17
Оценка:
Здравствуйте, VTT, Вы писали:

VTT>Здравствуйте, _hum_, Вы писали:


__>>- первый раз пробегает по тексту программы и заносит себе в память информацию о том, какие функции в программе объявлены (какие у них сигнатуры), и где у каждой объявленной функции определение (текст тела функции);


VTT>Дело в том, что как раз определения функции (текст тела функции) во время компиляции у компилятора может и не быть (я бы даже сказал что обычно нет).

VTT>Вот представьте, что класс C_B делает кто-то другой, а вам дает только заголовочный файл с объявлением этого класса и .dll (.lib) с его реализацией. А кода тела функции нет. И так со всеми системными и библиотечными функциями.
VTT>Даже если у вас есть код функции, он будет виден компилятору только если она inline или проект собирается с LTCG.

ну, разве только если с dll, потому как при статической компоновке (.lib) теоретически есть возможность перед построение окончательного кода, просмотреть библиотеки (почему-то интуитивно кажется, что выполнить алгоритм можно и по ассемблерному коду, зная изначально, какие типы участвуют в сигнатуре. а если и нет, то на будущее можно просто добавлять в них необходимую информацию).
но вообще, контраргумент понял — данное понятие на текущий момент не допускает раздельной компиляции...

__>>upd. может, вы имели в виду виртуальные функции? ну, так о них пока речь не шла (там можно либо все проверять, либо договориться, что в таких случаях виртуальные использовать нельзя).


VTT>Виртуальные я тоже имел ввиду. В начале вы вроде как упоминали сигнал-слоты, и на ум сразу приходит qt с его qobject и повальной виртуальностью.


не, я не люблю виртуальность, потому пока стараюсь обходиться статическим вариантом реализации сигналов-слотов (boost::signals2, да и qt ввел уже возможность статической реализации).
Re: "class const - метод" - можно ли организовать?
От: Кодт Россия  
Дата: 24.09.15 10:18
Оценка:
Здравствуйте, _hum_, Вы писали:

__>Потому встал вопрос, есть ли в других языках или в новом стандарте с++ что-нибудь наподобие "class const — метода", который делает константными ЛЮБЫЕ this данного класса в своей области видимости, и тем самым предотвращает всякое изменение любого (а значит и заданного)объекта данного класса?


Навесить константность на все объекты теоретически можно тремя способами:

1) через покрытие кода (мечты, мечты...)
class X;

void foo(X* x) {
  bar(x);
  #pragma TURN CONST ON
  buz(x); // вот здесь - и далее вглубь - константность навешана на всё
  #pragma TURN CONST OFF
  bar(x);
  buz(x);
}

компилятор должен провалиться в bar() и неявно навесить там константность

2) через типы — например, на шаблонах (фактически, это то же покрытие кода) — гору кода переписать, либо выбрать другой язык (скалу)
struct Mutable { Immutable& turn_const_on() const; };
struct Immutable : Mutable {};

template<class Traits>
void foo(Traits& t, X* x) {
  bar(t, x);
  buz(t.turn_const_on(), x);
  buz(t, x); // константность включится по требованию
}

void bar(Mutable& t, X* x);
void buz(Immutable& t, X const* x);


3) через, внезапно, рантаймовые проверки.
Просто натыкать флажков и ассертов
class X {
#ifdef _DEBUG
  bool is_mutable = true;
  thread_local static bool all_mutable = true;

  void turn_mutable(bool m) { is_mutable = m; }
  static void turn_all_mutable(bool m) { all_mutable = m; }
  void assert_mutable() { assert(is_mutable && all_mutable); }
#else
  void turn_mutable(bool m) {}
  static void turn_all_mutable(bool m) {}
  void assert_mutable() {}
#endif
  .....
};

void foo(X* x) {
  bar(x);
  X::turn_all_mutable(false);
  buz(x);
  X::turn_all_mutable(true);
  bar(x);
  buz(x);
}


Я нарочно не вдаюсь в нюансы — понятно, что тут логика скорее не двоичная, а счётчика вложенных запретов. И под это дело можно и RAII присобачить, и делать это нужно будет грамотно...
Перекуём баги на фичи!
Re: "class const - метод" - можно ли организовать?
От: SaZ  
Дата: 24.09.15 10:45
Оценка:
Соседняя ветка про Qt с топик стартером позволит более просто сформулировать хотелку автора.

_hum_ хочет переложить написание логики приложения с разработчика на компилятор. Кто знаком с Qt, может почитать изначальный вопрос: http://rsdn.ru/forum/cpp.qt/6188183.flat#6188183
Автор: _hum_
Дата: 20.09.15
Re[7]: "class const - метод" - можно ли организовать?
От: B0FEE664  
Дата: 24.09.15 13:13
Оценка:
Здравствуйте, _hum_, Вы писали:

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


Тут я согласен.

__>погодите-погодите, кто говорил, что речь идет о динамическом связывании? во многих случаях (в том числе в моем) можно обойтись и статическим (никаких виртуальных функций, никаких observer-pattern, — обычная "магия шаблонов". см., например, библиотеку boost). но от этого проблема не пропадает (что указывает на ее общий характер).


Да, речь идёт о динамическом связывании, так как вы говорите об архитектуре сигнал-слот. Архитектура сигнал-слот сводится к динамическому созданию списков функций — других реализаций я не видел. (Я, кстати, и не уверен, что в принципе можно создать статический вариант этой архитектуры без использования шаблонных виртуальных методов, которых в С++ нет)

__>принципиальное отличие — вы можете и сами это проконтролировать (например, проверкой выполнения условия возможности удаления или использовать RAII). а вот отследить скрытые циклические зависимости, как в моем примере — это уже во многом неподъемная для программиста задача. потому и должен в этом случае приходить на помощь компилятор.


Я не вижу разницы. Нет никакой проблемы в том, чтобы узнать во время выполнения, что данная функция вызвана из самой себя через последовательность других функций.
И каждый день — без права на ошибку...
Re[8]: "class const - метод" - можно ли организовать?
От: _hum_ Беларусь  
Дата: 24.09.15 15:24
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Здравствуйте, _hum_, Вы писали:


__>>погодите-погодите, кто говорил, что речь идет о динамическом связывании? во многих случаях (в том числе в моем) можно обойтись и статическим (никаких виртуальных функций, никаких observer-pattern, — обычная "магия шаблонов". см., например, библиотеку boost). но от этого проблема не пропадает (что указывает на ее общий характер).


BFE>Да, речь идёт о динамическом связывании, так как вы говорите об архитектуре сигнал-слот. Архитектура сигнал-слот сводится к динамическому созданию списков функций — других реализаций я не видел. (Я, кстати, и не уверен, что в принципе можно создать статический вариант этой архитектуры без использования шаблонных виртуальных методов, которых в С++ нет)


возможно, дело в терминологии. я говорю лишь, что есть реализации сигнал-слот без использования виртуальных функций (просто используются более продвинутые варианты call back-функций, позволяющие на этапе компиляции отслеживать корректность (по типам) вызовов и писать код безо всяких понижающих приведений типов).

__>>принципиальное отличие — вы можете и сами это проконтролировать (например, проверкой выполнения условия возможности удаления или использовать RAII). а вот отследить скрытые циклические зависимости, как в моем примере — это уже во многом неподъемная для программиста задача. потому и должен в этом случае приходить на помощь компилятор.


BFE>Я не вижу разницы. Нет никакой проблемы в том, чтобы узнать во время выполнения, что данная функция вызвана из самой себя через последовательность других функций.


вот здесь хотелось бы поподробнее (у вас 1000 разных функций, которые друг друга вызывают, и нужно определить, есть ли вариант зацикливания).
Re[8]: "class const - метод" - можно ли организовать?
От: Ops Россия  
Дата: 24.09.15 15:39
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>без использования шаблонных виртуальных методов, которых в С++ нет


deleter у shared_ptr — это оно?
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[2]: "class const - метод" - можно ли организовать?
От: _hum_ Беларусь  
Дата: 24.09.15 15:45
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, _hum_, Вы писали:


__>>Потому встал вопрос, есть ли в других языках или в новом стандарте с++ что-нибудь наподобие "class const — метода", который делает константными ЛЮБЫЕ this данного класса в своей области видимости, и тем самым предотвращает всякое изменение любого (а значит и заданного)объекта данного класса?


К>Навесить константность на все объекты теоретически можно тремя способами:


К>1) через покрытие кода (мечты, мечты...)

К>
К>class X;

К>void foo(X* x) {
К>  bar(x);
К>  #pragma TURN CONST ON
К>  buz(x); // вот здесь - и далее вглубь - константность навешана на всё
К>  #pragma TURN CONST OFF
К>  bar(x);
К>  buz(x);
К>}
К>

К>компилятор должен провалиться в bar() и неявно навесить там константность



К>2) через типы — например, на шаблонах (фактически, это то же покрытие кода) — гору кода переписать, либо выбрать другой язык (скалу)

К>
К>struct Mutable { Immutable& turn_const_on() const; };
К>struct Immutable : Mutable {};

К>template<class Traits>
К>void foo(Traits& t, X* x) {
К>  bar(t, x);
К>  buz(t.turn_const_on(), x);
К>  buz(t, x); // константность включится по требованию
К>}

К>void bar(Mutable& t, X* x);
К>void buz(Immutable& t, X const* x);
К>




К>3) через, внезапно, рантаймовые проверки.

К>Просто натыкать флажков и ассертов
К>
К>class X {
К>#ifdef _DEBUG
К>  bool is_mutable = true;
К>  thread_local static bool all_mutable = true;

К>  void turn_mutable(bool m) { is_mutable = m; }
К>  static void turn_all_mutable(bool m) { all_mutable = m; }
К>  void assert_mutable() { assert(is_mutable && all_mutable); }
К>#else
К>  void turn_mutable(bool m) {}
К>  static void turn_all_mutable(bool m) {}
К>  void assert_mutable() {}
К>#endif
К>  .....
К>};

К>void foo(X* x) {
К>  bar(x);
К>  X::turn_all_mutable(false);
К>  buz(x);
К>  X::turn_all_mutable(true);
К>  bar(x);
К>  buz(x);
К>}
К>


К>Я нарочно не вдаюсь в нюансы — понятно, что тут логика скорее не двоичная, а счётчика вложенных запретов. И под это дело можно и RAII присобачить, и делать это нужно будет грамотно...


да, 1) — наверное как раз то, что нужно было бы — обобщение подхода с const-спецификаторами.
2) — немного запутанный и, как мне показалось, все-таки не решающий проблемы с косвенными изменениями (как в исходном моем примере)
3) — это не подходит (уже обсуждалось ранее).
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.