开发者

How do I avoid copy constructor in the conversion function?

I am trying to convert between two classes and avoid a temporary obje开发者_如何学运维ct.

Here is my declaration for Square:

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

    // Conversion to Rectangle
    operator CRectangle();

    ~CSquare(void);
};

and here is my declaration for Rectangle:

class CRectangle
{
public:
    int length;
    int width;

    CRectangle(int length, int width);

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

    ~CRectangle(void);
};

Why does

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

invoke the copy constructor?

I have a conversion function:

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

but I'm still getting a temporary object.

How do I avoid the temporary object?


You can avoid copy construction by writing a conversion constructor in CRectangle:

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


Because you're copying a Rectangle.

I honestly don't know what else to say. Compilers are free to optimize away the call in the case you're showing, but they don't have to. Apparently yours is not.

Edit....

As to how to avoid it, you really can't. You could try to crank up the optimizations but it can be extremely difficult to see if you've succeeded, especially with such a small, trivial construct. If I where you I wouldn't be so worried about it unless I really found, by profiling my code, that an inordinate amount of time was being spent in that function. Then I'd be looking for ways to crunch the algorithms using the code to reduce copies.


How do I avoid the temporary object?

You don't. That's how conversions work. The temporary may be elided (constructing directly into the destination), but that is not required.

It sounds like you want move semantics, which are in C++0x. Even then, the temporary "exists", but it can be moved instead of copied, which, for types where it matters, is often much more efficient.

Is this square/rectangle case not really the situation you care about and only used here for an example?


I would assume since operator CRectangle returns an instance of CRectangle, the copy constructor is invoked for the return value.


In general this depends on the compiler. Return value optimization is done by most compiler. So instead of creating a temporary object and assign it to your object the copy Ctor from your object is called.

Also take a look here Copy constructor vs. return value optimization


A temporary CRectangle object is being created, then copied to convertedRect.


I can't tell which type of object you're saying has a temporary.

If the square, then you need to remove any excuse for the compiler to create one:

CSquare aSquare(10);

If the rectangle, then you shoudl use a converting constructor instead of an operator, as suggested by @PigBen:

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


In this particular case, you do it by not having the conversion function and instead use inheritance. 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)
    {}
};
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜