У меня есть следующий код.
class Wave {
int m_length;
data_type * m_data;
public:
Wave(){
blah...blah...blah
m_data = NULL;
m_length = 0;
cout << "Wave " << this << " created on " << m_data << " with m_length " << m_length << endl;
}
Wave(int len, data_type data){
blah...blah...blah
if (len) {
m_length = len;
m_data = new data_type [m_length];
} else {
m_length = 0;
m_data = NULL;
}
cout << "Wave " << this << " created on " << m_data << " with m_length " << m_length << endl;
}~Wave()
{
cout << "Wave " << this << " destructor on " << m_data << " started ";
if (m_length) delete[] m_data;
cout << "and finished " << endl;
};
Wave & operator+= (const Wave wave){
cout << __FUNCTION__ << ":" << __LINE__ << " m_length " << m_length << endl;
if (NULL != m_data){
data_type * tBuf = new data_type [m_length + wave.Length()];
copy (wave.begin(),wave.end(), copy (begin(),end(),iterator(tBuf)));
cout << "Wave " << this << " data on " << m_data << " moved onto " << tBuf;
delete[] m_data;
m_data = tBuf;
cout << " and deleted" << endl;
} else {
m_data = new data_type [wave.Length()];
copy (wave.begin(), wave.end(), begin());
cout << "Wave " << this << " data created on " << m_data << " of length " << wave.Length() << endl;
}
m_length += wave.Length();
cout << __FUNCTION__ << ":" << __LINE__ << " m_length " << m_length << endl;
return *this;
};
}main(){
blah..blah..blah
Wave sample;
for (......) {
cout << pulseNum << "-th High part: " << pulse->first << endl;
Wave tSample(x,y);
blah.blah.blah
sample += tSample;
cout << endl << pulseNum++ << "-th Low part: " << pulse->second << endl;
tSample = Wave(a,b);
blah.blah.blah
sample += tSample;
}
}
Ниже находится журнал выполнения этого кода
Wave 0x28fe34 created on 0 with m_length 0
0-th High part: 220
Wave 0x28fe54 created on 0xc60f00 with m_length 207
operator+=:211 m_length 0
Wave 0x28fe34 data created on 0xc610a8 of length 207
operator+=:230 m_length 207
Wave 0x28fe9c destructor on 0xc60f00 started and finished
0-th Low part: 320
Wave 0x28febc created on 0xc61250 with m_length 301
Wave 0x28febc destructor on 0xc61250 started and finished
operator+=:211 m_length 207
Wave 0x28fe34 data on 0xc610a8 moved to 0xc61250 and deleted
operator+=:230 m_length 508
Wave 0x28fee0 destructor on 0xc61250 started and finished
Wave 0x28fe54 destructor on 0xc61250 started and finished
Самым странным для меня является то, что деструктор вызывается чаще, чем конструктор. Более того, он был вызван для объектов, которые никогда не создавались ранее, но для одного и того же адреса данных.
Как это может быть?
Если вы хотите упростить свой код, просто определите std::vector<data_type> m_data
элемент данных, вместо использования необработанных указателей (data_type * m_data
).
Таким образом, компилятор автоматически сгенерировать правильный конструктор копирования, оператор копирования = (а также переместить семантику для компиляторов, совместимых с C ++ 11) и деструктор для вашего класса (автоматически сгенерированный конструктор копирования, оператор оператора = и деструктор будут работать по элементам, например, автоматически сгенерированная копия конструктор будет вызывать конструкторы копирования для каждого члена данных вашего класса).
Распределить данные вместо:
m_data = new data_type [m_length];
использовать:
m_data.resize(m_length);
Вы также можете избавиться от m_length
член данных, так как std::vector
знает свой собственный размер (вы можете получить к нему доступ через std::vector::size()
метод).
Обратите внимание, что std::vector
хранит все его элементы в одной непрерывной области памяти (например, new[]
); Вы можете получить доступ к началу этой области, используя &m_data[0]
,
Wave
имеет сгенерированный компилятором конструктор копирования, для которого вы не видите выходных данных.
Этот конструктор копирования вызывается, например, для создания объекта, который является параметром Wave & operator+= (const Wave wave)
,