воскресенье, 11 декабря 2011 г.

Запрет на создание не константных объектов


В процессе обдумывания одной безумной идеи, про которую я пока никому не расскажу, появилась интересная задачка. Необходимо запретить пользователю класса создавать не константные объекты.  Зачем? Надо. Ради спортивного интереса.
Решений тут есть несколько. Я опишу один из ненормальных, но теоретически интересных.






class A
{
private:
 class privA
 {
 public:
  privA(int n){}
  void foo() const {}
  void bar(){}
 };
public:
 typedef const privA constPrivA;
};
 
typedef A::constPrivA A_constPrivA;
 
int main()
{
 //A::privA a; // : cannot access private class declared in class A
 
 A_constPrivA a(10);
 a.foo();
 //a.bar(); // : cannot convert 'this' pointer from 'A_constPrivA' to 'A::privA &'
 
 return 0;
}

Идея в том, что класс  - это тоже пространство имён, причём умное. В классе есть приватная секция имён. Описывая нужный нам класс внутри этой секции другого класса, мы получаем полную невидимость  снаружи.    Здесь класс privA не виден вне класса A. Соответственно вообще нельзя создать объект этого класса.
Для того чтобы разрешить создание констант мы объявляем typedef в публичной секции. Цель достигнута: константу создать можно, а переменную нет.
Забавно, жаль только этот запрет можно обойти воспользовавшись ключевым словом auto, появившемся (изменившим свой смысл) в C++11. Код, приведённый ниже, не вызывает у 10 студии никаких нареканий:

auto b = a;
b.bar(); // без ошибок, так как b уже не константна

Комментариев нет:

Отправить комментарий