Недоработки компилятора в неявном операторе копирования

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Alexey Navoykov
4570
Alexey Navoykov  

Хочу обратить внимание разработчиков, что нынешняя реализация неявного оператора копирования в MQL сделана некорректно.   Рассмотрим две ситуации.

1.  

class NonCopyable
{
 private: void operator=(const NonCopyable&);
};

class A : public NonCopyable
{
};

void OnInit()
{
  A a;
  a=a;  // Нет ошибки. А должна быть!
}

Базовый класс не позволяет копировать себя (оператор копирования недоступен),  а значит и производный класс не должен копироваться.  Но в MQL это не учтено.


2.

class A
{ 
  int _a;
 public:
  A(int a=0) { _a=a; }
};

class B : public A
{
  int _b;
  int _axb;
 public: 
  B(int a, int b) : A(a) { _b=b; _axb=a*b; }
};


void OnInit()
{
  B b(2, 3);
  A a;
  b=a;  // Нет ошибки. А должна быть!
}

В данном случае у объекта b сработал неявный оператор =(A &), что неправильно, т.к. неявный оператор должен создаваться только для того типа, которым объявлен данный объект, т.е. operator=(B &).  Таким образом, объект может копироваться только полностью.  А здесь происходит частичное замещение внутренностей объекта, в результате чего объект стал некорректным:   _axb уже не равняется a*b  как должно было быть.

Можно конечно попытаться защититься от такого копирования, объявив в классе B приватный operator=(A &),  однако в общем случае цепочка наследования у нас может быть гораздо длиннее. Соответственно для всех предыдущих классов в этой цепочке нужно делать такую же защиту от копирования в нашем классе B.    А если в эту цепочку будут добавляться промежуточные классы?  Придётся помнить, что в неком классе-потомке нужно прописать для них защиту от копирования...  В общем, неправильно это всё.


C++ в обоих ситуациях, разумеется, выдаёт ошибки.

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий