#c #visual-c #c 11 #copy-constructor #deleted-functions
#c #visual-c #c 11 #копировать-конструктор #удаленные функции
Вопрос:
IDE — Visual Studio Express 2013 для рабочего стола
C 11
Проблема — у меня есть класс, который, по-видимому, копируется (с использованием конструктора копирования). Если я объявлю конструктор копирования следующим образом:
MyClass(const MyClassamp;) = delete;
Он жалуется на ссылку на удаленную функцию. Я уже дважды просмотрел весь свой код и не могу найти, куда будет скопирован экземпляр класса.
Есть ли какой-либо способ найти, откуда берется ссылка?
Я пытался определить конструктор копирования с точкой останова в нем, но она никогда не попадала.
Обновить
Извините, это действительно показывает, где находится ссылка — в некотором распределителе в STL. Мне удалось отследить ее до вызова std::vector::emplace_back(), который должен вызвать копирование. Я изучу это.
Обновление 2
Я такой тупица — у меня был вектор MyClass…
Комментарии:
1. Это было бы ошибкой компилятора, и любой приличный компилятор точно сказал бы вам, где возникает ошибка.
2. Вы пытались очистить и перестроить проект?
3. Выполните поиск по
MyClass x=y
,MyClass x(y)
иMyClass* x = new MyClass(y)
.4. Чтобы увеличить ваши шансы на получение значимого ответа (и избежать отрицательных отзывов), пожалуйста, отправьте sscce.org и скопируйте-вставьте все полученное сообщение об ошибке компилятора. Еще лучше, если вы включите все предупреждения, перекомпилируете, а затем скопируете и вставите все предупреждения.
5. О, также проверьте, отправляете ли вы в функцию или возвращаете из функции
MyClass
экземпляр по значению . Я полагаю, что конструктор копирования неявно вызывается в обоих случаях, чтобы реплицировать этот экземпляр в стеке.
Ответ №1:
Возможно, вы столкнулись со следующей ошибкой компилятора:
http://connect.microsoft.com/VisualStudio/feedback/details/889420/issue-with-delete
В нем говорится, что IDE (IntelliSense) выдает жалобы, в то время как компилятор этого не делает, что объясняет, почему вы не опубликовали никакого сообщения об ошибке компилятора и почему вы на самом деле могли бы выполнить скомпилированную программу с точками останова в первую очередь.
Саму ошибку легко воспроизвести:
struct Example
{
Example() {}
Example(Example const amp;) = delete;
};
Example f()
{
return Example();
}
int main()
{
Example e = f();
}
Скомпилирован с помощью VC 2013 следующим образом:
cl /nologo /EHsc /W4 /Za stackoverflow.cpp
Нет ошибки, нет предупреждения.
Теперь, если вы перейдете к http://www.compileonline.com/compile_cpp11_online.php вместо этого скомпилируйте тот же код с помощью GCC 4.7.2, есть ожидаемые ошибки компилятора:
main.cpp: In function ‘Example f()’:
main.cpp:9:18: error: use of deleted function ‘Example::Example(const Exampleamp;)’
return Example();
^
main.cpp:4:3: error: declared here
Example(Example const amp;) = delete;
^
main.cpp: In function ‘int main()’:
main.cpp:14:17: error: use of deleted function ‘Example::Example(const Exampleamp;)’
Example e = f();
^
main.cpp:4:3: error: declared here
Example(Example const amp;) = delete;
^
Итак, на самом деле у вас две проблемы:
-
В вашем компиляторе обнаружена ошибка. Это может быть решено только путем обновления до более новой версии, если / когда она будет доступна.
-
Ваш код вызывает конструктор копирования для класса, который не разрешает копирование.
Вторую проблему можно решить, рассмотрев правила, по которым C копирует объект «косвенно» — или требует присутствия конструктора копирования , даже если фактическое копирование оптимизировано. Проверьте код еще раз в поисках следующих случаев:
- Передача по значению.
void f(MyClass obj);
. - Возврат по значению.
MyClass f();
. - Выбрасывание.
throw MyClass();
Первая ошибка легко исправляется:
void f(MyClass const amp;obj);
Остальные требуют более тщательной переработки, потому что возврат или выбрасывание напрямую противоречит идее предотвращения копий.
Комментарии:
1. Я думаю, проблема скорее в том, что где-то в моем коде выполняется явное или неявное копирование в MyClass. Я хочу удалить это, поскольку я хочу, чтобы MyClass был «не копируемым». Проблема заключается в поиске ссылки на удаленную функцию.
2. @Brett: Еще что вы имеете в виду, говоря, что где-то есть явная или неявная копия? Это именно то, что я объяснил во второй половине моего ответа, где я привел примеры неявных копий.