如何在转换函数中避免复制构造函数?

时间:2011-02-01 16:34:16

标签: c++ visual-c++

我正在尝试在两个类之间进行转换,并避免使用临时对象。

以下是Square的声明:

class CSquare
{
public:
    int dimension;
    CSquare(int dimension);

    // Conversion to Rectangle
    operator CRectangle();

    ~CSquare(void);
};

这是我对Rectangle的声明:

class CRectangle
{
public:
    int length;
    int width;

    CRectangle(int length, int width);

    //Copy Constructor
    CRectangle(const CRectangle& anotherRectangle); 

    ~CRectangle(void);
};

为什么

CSquare aSquare = CSquare(10);
    CRectangle convertedRect = (CRectangle) aSquare;

调用复制构造函数?

我有转换功能:

CSquare::operator CRectangle(){
    return CRectangle(CSquare::dimension,CSquare::dimension);
}

但我仍然得到一个临时对象。

如何避开临时对象?

8 个答案:

答案 0 :(得分:5)

您可以通过在CRectangle中编写转换构造函数来避免复制构造:

CRectangle::CRectangle(const CSquare & sq)
    :length(sq.dimension),
     width(sq.dimension)
{}
...
...
CSquare aSquare(10);
CRectangle convertedRect(aSquare);

答案 1 :(得分:2)

因为你正在复制一个矩形。

老实说,我不知道还能说些什么。在你展示的情况下,编译器可以自由地优化掉电话,但他们没有必要。显然你的不是。

编辑...

至于如何避免它,你真的不能。你可以尝试加速优化,但是如果你成功的话可能会非常困难,特别是对于这么小的,微不足道的结构。如果我在哪里,我就不会那么担心它,除非我真的通过剖析我的代码找到了这个功能花费了过多的时间。然后我会寻找方法来使用代码来缩小算法以减少副本。

答案 2 :(得分:1)

  

如何避开临时对象?

你没有。这就是转换的工作方式。可以省略临时(直接构建到目的地),但这不是必需的。

听起来你想要移动语义,它们在C ++ 0x中。即使这样,临时“存在”,但它可以移动而不是复制,对于重要的类型,它往往更有效。

这个方形/矩形的情况不是你真正关心的情况,只是在这里用作一个例子吗?

答案 3 :(得分:0)

正在创建临时CRectangle对象,然后将其复制到convertedRect。

答案 4 :(得分:0)

我认为,因为operator CRectangle返回CRectangle的实例,所以会为返回值调用复制构造函数。

答案 5 :(得分:0)

一般来说,这取决于编译器。 返回值优化由大多数编译器完成。因此,不是创建临时对象并将其分配给对象,而是调用对象中的副本Ctor。

另请查看Copy constructor vs. return value optimization

答案 6 :(得分:0)

我不知道你说的那种对象是暂时的。

如果是正方形,那么你需要删除编译器创建一个的借口:

CSquare aSquare(10);

如果是矩形,那么你应该按照@PigBen的建议使用转换构造函数而不是运算符:

Rectangle::CRectangle(const CSquare & sq)
    :length(sq.dimension),
     width(sq.dimension)
{}
// And then:
CRectangle convertedRect(aSquare);

答案 7 :(得分:0)

在这种特殊情况下,您可以通过不使用转换功能来代替使用继承。 E.g:

class CRectangle
{
public:
    int length;
    int width;

    CRectangle(int length, int width);
};

class CSquare : public CRectangle
{
public:
    CSquare(int dimension) : length(dimension), width(dimension)
    {}
};