我相信我可能要么滥用OOP,要么在类构造函数中对内存分配做错了。
我将用简化的例子说明我在做什么:
class data
{
data(int n) : m_data(new double[n])
{
}
virtual ~data()
{
delete [] m_data;
}
double min() { ... }
double max();
double mean(); // return minimum, maximum and mean values
double *m_data;
}
class dual_data : public data
{
dual_data(int n) : m_data(new double[2*n])
{
}
}
我相信这会导致灾难性的内存泄漏。 (应该清楚为什么,因为一个构造函数在另一个构造函数之前分配内存,然后用另一个调用new
覆盖指针。)
如果还不清楚,我有两个类:一个是类似于std::vector
的类,它为我处理内存中的数据存储,另一个是执行相同操作的派生类,但是期望数据的格式为x,y对而不是单个值。这样做的原因是x,y对可以用不同于矢量的方式处理。例如,使用统计数据处理来完全计算相关性或其他内容。但是,能够调用继承自min()
的类max()
中的函数mean()
,dual_data
和data
仍然很有用。
我该怎么做才能纠正内存泄漏?
答案 0 :(得分:2)
也许这应该做:你告诉基类分配一个2 * n元素的数组。除了基类负责释放内存。不需要析构函数。
class dual_data : public data
{
dual_data(int n) : data(2*n)
{
}
}
答案 1 :(得分:0)
由于data
已经有一个双打数组,而不是尝试用它来捣乱,只需在dual_data
中创建另一个并行数组的双精度数。
class data
{
public:
data(int n) : m_data(new double[n])
{
}
virtual ~data()
{
delete [] m_data;
}
double *m_data;
}
class dual_data : public data
{
public:
dual_data(int n) : data(n), d_data(n)
{
}
virtual ~dual_data() {
delete[] d_data;
}
double* d_data;
}
现在,您的dual_data
类具有原始m_data
数组,以及相同长度的其他d_data
数组,其元素将用于该对中的第二个元素。例如,第0对将是(m_data[0], d_data[0])
。
答案 2 :(得分:0)
您无法初始化父类的变量。它不会编译。
如果你在构造函数中进行了内存泄漏,那么你可能会发生内存泄漏。
class dual_data : public data
{
public:
dual_data(int n) : data(n)
{
m_data = new double[2*n];
}
};
然而,你的责任是做得好。一个伟大的粉末是一个很大的责任。
你做到了这一点:
class dual_data : public data
{
public:
dual_data(int n) : data(2*n) {}
};
更好的解决方案是不使用继承。它总是更好Composititon over inheritance。
#include "data.h"
class dual_data {
public:
dual_data( int n ) : data_1(n), data_2(n) {}
private:
data data_1;
data data_2;
};
更好地使用接口:
class CdataIf
{
public:
virtual ~CDataIf() = 0;
virtual double min() = 0;
virtual double max() = 0;
virtual double mean() = 0;
};
class data : public CdataIf { ... };
class data_dual : public CdataIf { ... };
答案 3 :(得分:0)
首先,实现基本向量类(如果可能,直接使用std::vector<double>
)
class vector_of_double
{
public:
explicit vector_of_double(std::size_t mSize) :
mValues(new double[size]{}),
mSize(size)
{}
~vector_of_double() { delete[] mValues; }
// implement these if required
// deleted for now to Respect rule of 3(5) as default implementation is incorrect.
vector_of_double(const vector_of_double&) = delete;
vector_of_double& operator = (const vector_of_double&) = delete;
vector_of_double(const vector_of_double&&) = delete;
vector_of_double& operator = (const vector_of_double&&) = delete;
std::size_t size() const { return mSize; }
// Implement required missing stuff if required as push_back, resize, empty, clear
// introduction of mCapacity may be required.
double operator[] (std::size_t index) const { return mValues[index]; }
double& operator[] (std::size_t index) { return mValues[index]; }
// To be able to use for range and iterator style
const double* begin() const { return mValues; }
const double* end() const { return mValues + mSize; }
double* begin() { return mValues; }
double* end() { return mValues + mSize; }
private:
double* values;
std::size_t size;
};
然后你可以实现你的类(不用担心内存管理):
class data
{
public:
explicit data(int n) : m_data(n) {}
// Or use your own implementation
// TODO: Handle case with empty vector
double min() const { return *std::min_element(m_data.begin(), m_data.end()); }
double max() const { return *std::max_element(m_data.begin(), m_data.end()); }
double mean() const {return std::accumulate(m_data.begin(), m_data.end(), 0.) / m_data.size();}
private:
vector_of_double m_data;
};
和
class dual_data
{
public:
explicit dual_data(int n) : m_data1(n), m_data2(n) {}
// your functions as
std::pair<double, double> means() double {return {m_data1.means(), m_data2.means()};}
private:
data m_data1;
data m_data2;
};
答案 4 :(得分:0)
我会采用不同的方法,而是声明一个包含min,max和mean的接口。然后创建实现接口但具有不同底层结构的类。
struct ICommon
{
virtual double min() = 0;
virtual double max() = 0;
virtual double mean() = 0;
};
class Data : public ICommon
{...};
class DualData : public ICommon
{...};