我正在尝试在两个类之间进行转换,并避免使用临时对象。
以下是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);
}
但我仍然得到一个临时对象。
如何避开临时对象?
答案 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。
答案 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)
{}
};