复制构造函数未被调用

时间:2010-10-20 12:43:02

标签: c++

我有一个在堆上分配内存的类,然后析构函数释放它。我的拷贝构造函数由于某种原因从未被调用过,我不明白为什么。这是我的实施:

 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");

永远不会调用复制构造函数代码(设置断点)。因此,当临时对象在重构对象中具有无效指针时,我的问题在临时对象被破坏时变得无效。

如何调用我的复制构造函数?

由于

6 个答案:

答案 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;
}

另请注意,您的复制构造函数不完整,因为heightwidth成员未被复制:

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;
}