如何解决C++ 使用复制构造函数避免临时对象销毁
我有一个 Tree 的 std::vector
,一个自定义类型,并且我有一个循环将全部 Tree 推回向量。问题是:我需要推回 temporary Tree 对象,但同时,我必须避免它们被释放(我认为向 Tree 类添加一个 rvalue 引用构造函数 可以解决这个问题,但它没有)。
树类:
class Tree
{
public:
Tree();
Tree(Coords,Pixel,uint8_t);
Tree(const Tree&);
Tree(const Tree&&);
~Tree();
Tree& operator=(const Tree&);
Tree& operator=(const Tree&&);
void draw();
void chop(uint8_t);
Coords getCoords() const {return log->coords;}
const Log& getLog() const
{
return *log;
}
const Crown& getCrown() const
{
return *crown;
}
private:
Log* log;
Crown* crown;
};
Tree::Tree():
log(nullptr),crown(nullptr)
{
}
Tree::Tree(Coords c,Pixel wd,Pixel lvs,uint8_t h):
log(new Log(c,wd,h)),crown(new Crown({c.x,static_cast<coordsCounter>(c.y + h)},lvs,getRandBetweenEqu(3,4)))
{
draw();
}
Tree::Tree(const Tree& tree):
log(new Log(tree.log->coords,tree.log->texture,tree.log->height)),crown(new Crown(tree.crown->coords,tree.crown->texture,tree.crown->width))
{
draw();
}
Tree::Tree(const Tree&& tree):
log(new Log(tree.log->coords,tree.crown->width))
{
draw();
}
Tree& Tree::operator=(const Tree& tree)
{
if(log != nullptr) delete log;
if(crown != nullptr) delete crown;
log = new Log(*tree.log);
crown = new Crown(*tree.crown);
return *this;
}
Tree& Tree::operator=(const Tree&& tree)
{
if(log != nullptr) delete log;
if(crown != nullptr) delete crown;
log = new Log(*tree.log);
crown = new Crown(*tree.crown);
return *this;
}
void Tree::draw()
{
log->draw();
crown->draw();
}
Tree::~Tree()
{
chop(0);
}
void Tree::chop(uint8_t h)
{
if(crown != nullptr)
{
delete crown;
crown = nullptr;
}
if(h == 0)
{
if(log != nullptr)
{
delete log;
log = nullptr;
}
} else
{
if(h <= log->height)
{
log->chop(h);
}
}
}
推回树的函数:
void growTrees(uint8_t m,uint8_t M)
{
Coords treeCoords;
for(coordsCounter i = 5; i < grid.getMaxXY().x - 4; i += getRandBetweenEqu(m,M))
{
if((treeCoords = getFirstBlock({i,static_cast<coordsCounter>(grid.getMaxXY().y - 1)},'s',grasstexture) + Coords{0,1}) != Coords{0,1})
{
trees.push_back(Tree(treeCoords,woodTexture,leavesTexture,getRandBetweenEqu(minTreeHeight,maxTreeHeight)));
}
}
}
解决方法
您的移动构造函数/赋值运算符实际上是在复制对象,它们应该采用非常量右值引用并将移动的对象设置为某个空值。
Tree::Tree(Tree&& tree):
log(std::exchange(tree.log,nullptr)),crown(std::exchange(tree.crown,nullptr))
{
draw();
}
Tree& Tree::operator=(Tree&& tree)
{
std::swap(tree.log,log);
std::swap(tree.crown,crown);
return *this;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。