Я догоняю современный C ++, практикую семантику перемещения.
Я сделал очень простой тестовый пример:
- создать экземпляр
- переместить-построить новый экземпляр
Я заметил, что когда мои экземпляры уничтожаются, оба деструктора называются:
- один из экземпляров, созданных при перемещении, где данные являются действительными
указатель
- тот из исходного экземпляра, где указатель данных был удален
и установите значение nullptr при перемещении
Мой код, удаляющий nullptr, причиняет мне неудобство, вот вопросы:
- заключается в том, что (удаление nullptr) даже допустимой операции (т. Е. Приводит ли это к UB;
в итоге вылетает мое приложение)?
- или мое определение оператора move-constructor / move-assignement
неправильно?
- Я нашел этот похожий вопрос , но он все еще неясен, в частности, если удаление nullptr является проблемой. Должен ли я избежать этого, проверив указатель в деструкторе? Если так, то кажется, что использование семантики перемещения вызывает систематическое неправильное поведение.
Мой вывод для теста (код ниже):
Test 5
new 0x7512b0
move_new 0x7512b0
delete[] 0x7512b0
delete[] 0
Вывод delete [] 0 - это то, что размалывает мои механизмы.
Вот главное:
#include <iostream>
#include "test5.h"
int main()
{
std::cout << "Test 5" << std::endl;
test5 rule5;
test5 rule5move = std::move(rule5);
// rule5 = std::move(rule5move);
return 0;
}
и вот test5.h:
#ifndef TEST5_H
#define TEST5_H
class test5
{
public:
test5(): data(new float[10]){
std::cout << "\tnew " << data << std::endl;
for (int i = 0; i < 10; i++)
data[i] = float(i);
}
~test5(){
std::cout << "\tdelete[] " << data << std::endl;
delete[] data;
}
// copy constructor
test5(const test5& t) : data(new float[10]){
std::cout << "\tcopy " << data << std::endl;
std::copy(t.data, t.data + 10, data);
}
// copy operator
test5& operator=(const test5& t){
std::cout << "\tassign " << data << std::endl;
std::copy(t.data, t.data + 10, data);
return *this;
}
// move constructor
test5(test5&& t): data(new float[10]){
delete[] data;
data = t.data;
std::cout << "\tmove_new " << data << std::endl;
t.data = nullptr;
}
// move operator
test5& operator=(test5&& t){
delete[] data;
data = t.data;
std::cout << "\tmove_assign " << data << std::endl;
t.data = nullptr;
return *this;
}
private:
float* data;
};
#endif // TEST5_H