在 class 中使用 std::unique_ptr 赋值运算符,
In class assign operator with std::unique_ptr,
我的 BitMap
class 中的 operator=
有问题。我有一些内存泄漏,所以我决定从原始指针更改为 std::unique_ptr
。当我这样做时,我注意到每当我使用我的
BitMap
赋值运算符,我得到一个错误:
function "sp::BitMap::BitMap(const sp::BitMap &)" (declared implicitly) cannot be referenced -- it is a deleted function
.h 文件
#include "color.h"
#include "spmath.h"
#include <memory>
namespace sp
{
//Bitmap: saves pixel position in the image
class BitMap
{
public:
BitMap();
BitMap(const vector2i& pos, const vector2i& size);
~BitMap() { }
BitMap& operator=(BitMap bm);
void marge(BitMap& bm);
void marge(BitMap* bm, int obj_count);
void calculateNewRect(const BitMap& bm, sp::vector2i* pos, sp::vector2i* size);
void calculateNewRect(const BitMap* bm, int obj_count, sp::vector2i* pos, sp::vector2i* size);
void margeToBitMap(BitMap& target, BitMap& bm);
public:
//bool* m_pixelMap;
std::unique_ptr<bool[]> m_pixelMap;
vector2i m_startPos;
vector2i m_size;
};
//--------------------------
}
.cpp 文件
//-----------------------------------------------------
sp::BitMap& sp::BitMap::operator=(BitMap bm)
{
//if(this->m_pixelMap != nullptr)
// this->clear(); //Delete last pixel_map
this->m_startPos = bm.m_startPos; //Copy position
this->m_size = bm.m_size; //Copy size
this->m_pixelMap.reset(bm.m_pixelMap.release()); //Copy ptr to pixel_map
//bm.m_pixelMap = nullptr; //Delete pointer to pixel map
return *this;
}
//-----------------------------------------------------
//-----------------------------------------------------
void sp::BitMap::marge(BitMap& bm) //Margeing to one object
{
//Calcuating new bitmap size
vector2i new_pos = this->m_startPos;
vector2i new_sum_size = this->m_size + new_pos;
calculateNewRect(bm, &new_pos, &new_sum_size);
vector2i new_size = new_sum_size - new_pos;
BitMap marged(new_pos, new_size);
//------------------------------
//Mergeing
margeToBitMap(marged, *this);
margeToBitMap(marged, bm);
//------------------------------
*this = marged; //ERROR
}
//-----------------------------------------------------
您按值获取了 operator=
的参数,因此这需要将 marged
复制到写入的参数中。但是,隐式复制构造函数格式错误,因为无法复制 m_pixelMap
。
相反,考虑移动分配,因为本地无论如何都会被摧毁:
*this = std::move(marged);
此步构造论证。隐式移动构造函数格式正确(假设 vector2i
是可移动的)。
作为一种替代方法,请考虑用 std::vector<std::byte>
替换一个或多个数据成员。这将使复制、移动和销毁全部自动化。
如果标志位打包在您的情况下是可以接受的(很难说,因为我们没有看到 m_pixelMap
在任何地方实际使用过),那么您可以使用专业化 std::vector<bool>
。
在使用 std::vector<bool>
进行一些测试后,我发现此解决方案消耗过多 CPU 并且内存使平均 FPS 从 80 下降到 6。我也无法 std::move()
为我的目的工作。所以我回到原来的解决方案并处理内存泄漏。感谢@cdhowie 指出 unique_ptr
复制问题,我以后会记住的。
.h 文件
namespace sp
{
//Bitmap: saves pixel position in the image
class BitMap
{
public:
BitMap();
BitMap(const vector2i& pos, const vector2i& size);
~BitMap();
BitMap& operator=(BitMap bm);
void clear();
void marge(BitMap& bm);
void marge(BitMap* bm, int obj_count);
void calculateNewRect(const BitMap& bm, sp::vector2i* pos, sp::vector2i* size);
void calculateNewRect(const BitMap* bm, int obj_count, sp::vector2i* pos, sp::vector2i* size);
void margeToBitMap(BitMap& target, BitMap& bm);
public:
bool* m_pixelPosMap;
vector2i m_startPos;
vector2i m_size;
};
//--------------------------
}
.cpp 文件
sp::BitMap::BitMap() :
m_startPos(sp::vector2i(0, 0)) , m_size(sp::vector2i(0, 0)), m_pixelPosMap(nullptr)
{
}
sp::BitMap::BitMap(const vector2i& pos, const vector2i& size) :
m_startPos(pos), m_size(size)
{
m_size.x;
m_size.y;
int full_size = m_size.x * m_size.y;
m_pixelPosMap = new bool[full-size];
memset(m_pixelPosMap, 0, full_size); //Clear pixelMap
}
sp::BitMap::~BitMap()
{
}
//-----------------------------------------------------
//-----------------------------------------------------
sp::BitMap& sp::BitMap::operator=(BitMap bm)
{
this->clear(); //Delete last pixel_map
this->m_startPos = bm.m_startPos; //Copy position
this->m_size = bm.m_size; //Copy size
this->m_pixelPosMap = bm.m_pixelPosMap; //Copy ptr to pixel_map
bm.m_pixelPosMap = nullptr; //Delete pointer to pixel map
return *this;
}
//-----------------------------------------------------
void sp::BitMap::clear()
{
if(m_pixelPosMap != nullptr)
delete[] m_pixelPosMap;
}
//-----------------------------------------------------
void sp::BitMap::marge(BitMap& bm) //Margeing to one object
{
//Calcuating new bitmap size
vector2i new_pos = this->m_startPos;
vector2i new_sum_size = this->m_size + new_pos;
calculateNewRect(bm, &new_pos, &new_sum_size);
vector2i new_size = new_sum_size - new_pos;
BitMap marged(new_pos, new_size);
//------------------------------
//Margeing
margeToBitMap(marged, *this);
margeToBitMap(marged, bm);
//------------------------------
*this = marged;
}
//-----------------------------------------------------
我的 BitMap
class 中的 operator=
有问题。我有一些内存泄漏,所以我决定从原始指针更改为 std::unique_ptr
。当我这样做时,我注意到每当我使用我的
BitMap
赋值运算符,我得到一个错误:
function "sp::BitMap::BitMap(const sp::BitMap &)" (declared implicitly) cannot be referenced -- it is a deleted function
.h 文件
#include "color.h"
#include "spmath.h"
#include <memory>
namespace sp
{
//Bitmap: saves pixel position in the image
class BitMap
{
public:
BitMap();
BitMap(const vector2i& pos, const vector2i& size);
~BitMap() { }
BitMap& operator=(BitMap bm);
void marge(BitMap& bm);
void marge(BitMap* bm, int obj_count);
void calculateNewRect(const BitMap& bm, sp::vector2i* pos, sp::vector2i* size);
void calculateNewRect(const BitMap* bm, int obj_count, sp::vector2i* pos, sp::vector2i* size);
void margeToBitMap(BitMap& target, BitMap& bm);
public:
//bool* m_pixelMap;
std::unique_ptr<bool[]> m_pixelMap;
vector2i m_startPos;
vector2i m_size;
};
//--------------------------
}
.cpp 文件
//-----------------------------------------------------
sp::BitMap& sp::BitMap::operator=(BitMap bm)
{
//if(this->m_pixelMap != nullptr)
// this->clear(); //Delete last pixel_map
this->m_startPos = bm.m_startPos; //Copy position
this->m_size = bm.m_size; //Copy size
this->m_pixelMap.reset(bm.m_pixelMap.release()); //Copy ptr to pixel_map
//bm.m_pixelMap = nullptr; //Delete pointer to pixel map
return *this;
}
//-----------------------------------------------------
//-----------------------------------------------------
void sp::BitMap::marge(BitMap& bm) //Margeing to one object
{
//Calcuating new bitmap size
vector2i new_pos = this->m_startPos;
vector2i new_sum_size = this->m_size + new_pos;
calculateNewRect(bm, &new_pos, &new_sum_size);
vector2i new_size = new_sum_size - new_pos;
BitMap marged(new_pos, new_size);
//------------------------------
//Mergeing
margeToBitMap(marged, *this);
margeToBitMap(marged, bm);
//------------------------------
*this = marged; //ERROR
}
//-----------------------------------------------------
您按值获取了 operator=
的参数,因此这需要将 marged
复制到写入的参数中。但是,隐式复制构造函数格式错误,因为无法复制 m_pixelMap
。
相反,考虑移动分配,因为本地无论如何都会被摧毁:
*this = std::move(marged);
此步构造论证。隐式移动构造函数格式正确(假设 vector2i
是可移动的)。
作为一种替代方法,请考虑用 std::vector<std::byte>
替换一个或多个数据成员。这将使复制、移动和销毁全部自动化。
如果标志位打包在您的情况下是可以接受的(很难说,因为我们没有看到 m_pixelMap
在任何地方实际使用过),那么您可以使用专业化 std::vector<bool>
。
在使用 std::vector<bool>
进行一些测试后,我发现此解决方案消耗过多 CPU 并且内存使平均 FPS 从 80 下降到 6。我也无法 std::move()
为我的目的工作。所以我回到原来的解决方案并处理内存泄漏。感谢@cdhowie 指出 unique_ptr
复制问题,我以后会记住的。
.h 文件
namespace sp
{
//Bitmap: saves pixel position in the image
class BitMap
{
public:
BitMap();
BitMap(const vector2i& pos, const vector2i& size);
~BitMap();
BitMap& operator=(BitMap bm);
void clear();
void marge(BitMap& bm);
void marge(BitMap* bm, int obj_count);
void calculateNewRect(const BitMap& bm, sp::vector2i* pos, sp::vector2i* size);
void calculateNewRect(const BitMap* bm, int obj_count, sp::vector2i* pos, sp::vector2i* size);
void margeToBitMap(BitMap& target, BitMap& bm);
public:
bool* m_pixelPosMap;
vector2i m_startPos;
vector2i m_size;
};
//--------------------------
}
.cpp 文件
sp::BitMap::BitMap() :
m_startPos(sp::vector2i(0, 0)) , m_size(sp::vector2i(0, 0)), m_pixelPosMap(nullptr)
{
}
sp::BitMap::BitMap(const vector2i& pos, const vector2i& size) :
m_startPos(pos), m_size(size)
{
m_size.x;
m_size.y;
int full_size = m_size.x * m_size.y;
m_pixelPosMap = new bool[full-size];
memset(m_pixelPosMap, 0, full_size); //Clear pixelMap
}
sp::BitMap::~BitMap()
{
}
//-----------------------------------------------------
//-----------------------------------------------------
sp::BitMap& sp::BitMap::operator=(BitMap bm)
{
this->clear(); //Delete last pixel_map
this->m_startPos = bm.m_startPos; //Copy position
this->m_size = bm.m_size; //Copy size
this->m_pixelPosMap = bm.m_pixelPosMap; //Copy ptr to pixel_map
bm.m_pixelPosMap = nullptr; //Delete pointer to pixel map
return *this;
}
//-----------------------------------------------------
void sp::BitMap::clear()
{
if(m_pixelPosMap != nullptr)
delete[] m_pixelPosMap;
}
//-----------------------------------------------------
void sp::BitMap::marge(BitMap& bm) //Margeing to one object
{
//Calcuating new bitmap size
vector2i new_pos = this->m_startPos;
vector2i new_sum_size = this->m_size + new_pos;
calculateNewRect(bm, &new_pos, &new_sum_size);
vector2i new_size = new_sum_size - new_pos;
BitMap marged(new_pos, new_size);
//------------------------------
//Margeing
margeToBitMap(marged, *this);
margeToBitMap(marged, bm);
//------------------------------
*this = marged;
}
//-----------------------------------------------------