我有一个在堆上分配内存的类,然后析构函数释放它。我的拷贝构造函数由于某种原因从未被调用过,我不明白为什么。这是我的实施:
AguiBitmap::AguiBitmap( const AguiBitmap &bmp )
{
this->nativeBitmapPtr = al_clone_bitmap(bmp.nativeBitmapPtr);
}
AguiBitmap::AguiBitmap( char *filename )
{
if(!filename)
{
nativeBitmapPtr = 0;
return;
}
nativeBitmapPtr = al_load_bitmap(filename);
if(nativeBitmapPtr)
{
width = al_get_bitmap_width(nativeBitmapPtr);
height = al_get_bitmap_height(nativeBitmapPtr);
}
else
{
width = 0;
height = 0;
}
}
ALLEGRO_BITMAP* AguiBitmap::getBitmap() const
{
return nativeBitmapPtr;
}
然而, 当我做类似的事情时:
AguiBitmap bitmap;
bitmap = AguiBitmap("somepath");
永远不会调用复制构造函数代码(设置断点)。因此,当临时对象在重构对象中具有无效指针时,我的问题在临时对象被破坏时变得无效。
如何调用我的复制构造函数?
由于
答案 0 :(得分:12)
这段代码不会调用复制构造函数 - 它会调用赋值运算符(或复制赋值运算符):
// a helper `swap` function
void AguiBitmap::swap(AguiBitmap& a, AguiBitmap& b)
{
using std::swap; // enable the following calls to come from `std::swap`
// if there's no better match
swap(a.nativeBitmapPtr, b.nativeBitmapPtr);
swap(a.width, b.width);
swap(a.height,b.height);
}
AguiBitmap::AguiBitmap& operator=( const AguiBitmap &rhs )
{
// use copy-swap idiom to perform assignment
AguiBitmap tmp(rhs);
swap( *this, tmp);
return *this;
}
另请注意,您的复制构造函数不完整,因为height
和width
成员未被复制:
width = bmp.width;
height = bmp.height;
答案 1 :(得分:7)
AguiBitmap("somepath");
将调用:
AguiBitmap::AguiBitmap( char *filename )
,赋值将调用赋值运算符
调用你的拷贝构造函数,执行以下操作:
AguiBitmap bitmap;
AguiBitmap anotherBitmap(bitmap)
答案 2 :(得分:3)
您的代码调用 赋值运算符 ,而不是复制构造函数。可以为此代码
调用复制构造函数AguiBitmap bitmap = AguiBitmap("somepath");
但是编译器也可以优化它并执行相应的操作:
AguiBitmap bitmap("somepath");
但是,根据 Rule of Three ,当你有一个复制构造函数时,你很可能也需要一个赋值运算符(和一个析构函数) ,无论如何。所以你应该实施一个。
请参阅this answer,了解在复制构造和销毁之上实现分配的惯用方法。
答案 3 :(得分:2)
抱歉,这是作业,而不是副本
答案 4 :(得分:2)
您可以实施operator=
。为避免代码重复,请使用复制构造函数来实现它(因为它们应该完全相同)。这将导致调用复制构造函数,如果间接调用。
This question涵盖了如何安全有效地实施这些内容。
答案 5 :(得分:0)
你需要这样的东西:
AguiBitmap &AguiBitmap::operator=(const AguiBitmap &guiBitmap)
{
if(&guiBitmap == NULL)
{
//throw Exception
}
if(&guiBitmap != this)
{
//do the copying here
this->nativeBitmapPtr = al_clone_bitmap(guiBitmap.nativeBitmapPtr);
//...
}
return *this;
}