GCC требует открытого конструктора копирования для C++98

В одной из своих прошлых статей я рассказывал, что при возврате объектов GCC не использует конструктор копирования, сразу размещая объекты там, где они должны располагаться. Однако, в некоторых случаях GCC требует наличия открытого конструктора копирования.

Рассмотрим программу:

#include <stdio.h>

class MyClass
{
public:
  int getA() const
  {
    return a_;
  };
  
  explicit MyClass(int a) : a_(a) {};
  
#if ((__cplusplus) >= 201103L)
  MyClass& operator = (MyClass &&value)
  {    
    a_ = value.a_;
    value.a_ = 0;
    return *this;
  }; 
  
  MyClass(MyClass &&value) : a_(value.a_)
  {   
    value.a_ = 0;
  };  
#endif  
  
private:
  int a_;
  
  MyClass& operator = (const MyClass&)
  {    
    return *this;
  };
  
  MyClass(const MyClass&) {};
};

MyClass makeMyClass(int a)
{
  return MyClass(a);
}

int main()
{
  MyClass mc = makeMyClass(15);
  printf("a = %d\r\n", mc.getA());
  return 0;
}

В ней создается класс MyClass, который является перемещаемым, но не копируемым. Его конструктор копирования и оператор присваивания копированием объявлены закрытыми.

Функция makeMyClass возвращает экземпляр класcа MyClass. По сути она реализует что-то похожее на паттерн «фабрика классов».

Теперь главный вопрос: будет ли этот код работать?

Если передать GCC ключ -std=c++11, то данный пример нормально компилируется и работает. Но если ему передать ключ -std=c++98, то увидим ворох ошибок:

main.cpp: In function ‘MyClass makeMyClass(int)’:
main.cpp:35:3: error: ‘MyClass::MyClass(const MyClass&)’ is private
   MyClass(const MyClass&) {};
   ^
main.cpp:40:19: error: within this context
   return MyClass(a);
                   ^
main.cpp: In function ‘int main()’:
main.cpp:35:3: error: ‘MyClass::MyClass(const MyClass&)’ is private
   MyClass(const MyClass&) {};
   ^
main.cpp:45:30: error: within this context
   MyClass mc = makeMyClass(15);
                              ^

GCC ругается на закрытый конструктор копирования. Если объявить его открытым, то ошибка исчезнет. Однако это нарушит саму идею некопируемого класса.

Объявление функции makeMyClass дружественной лишь уменьшает количество ошибок, но не решает саму проблему.

Таким образом, в С++98 нельзя возвращать некопируемые объекты. По крайней мере для компилятора GCC.

 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *