提问人:Michel H 提问时间:3/23/2021 最后编辑:Vlad from MoscowMichel H 更新时间:3/23/2021 访问量:114
C++:两个自定义对象的总和,避免复制构造函数的重复调用
C++: Sum of two custom objects, avoid double call of copy constructor
问:
在下面的示例中,我有两个类,第一个动态分配一个整数,第二个是第一个类的容器。
当我对两个容器对象求和时 (),复制构造函数被调用两次。在我看来,第二个发生在函数的“return”语句期间。如何优化以避免复制构造函数的第二次调用?operator+()
operator+()
显然,这对于更复杂的应用程序来说是代表的,如果从逻辑上思考,只需要创建一个对象来获得总和(然后返回):
(这似乎是很多代码,但只有运算符和构造函数才能有效地进行求和。我避开了析构函数,以免使它更加混乱)。
主班:
int main()
{
NumberContainer a{1};
NumberContainer b{2};
NumberContainer c = a + b; // Copy constructor called twice!
return 0;
}
数字类:
class Number
{
public:
int* num;
Number(int num) : num{new int{num}}
{}
// Destructor...
};
容器类:
class NumberContainer
{
private:
Number _numObj;
public:
NumberContainer(int num) : _numObj{Number{num}}
{}
NumberContainer(const NumberContainer& source) : NumberContainer{*(source._numObj.num)}
{
std::cout<<"Copy constructor called" << std::endl;
}
NumberContainer(NumberContainer&& source) : NumberContainer(*(source._numObj.num))
{
std::cout<<"Move constructor called" << std::endl;
}
NumberContainer& operator=(const NumberContainer& source)
{
*(_numObj.num) = *(source._numObj.num);
std::cout<<"Copy assignment called" << std::endl;
return *this;
}
NumberContainer& operator=(NumberContainer&& source)
{
_numObj.num = source._numObj.num;
source._numObj.num = nullptr;
std::cout<<"Move assignment called" << std::endl;
return *this;
}
NumberContainer& operator+=(const NumberContainer& source)
{
*(_numObj.num) += *(source._numObj.num);
return *this;
}
NumberContainer operator+(const NumberContainer& source) const
{
NumberContainer copy{*this};
return copy+=source;
}
// Destructor...
};
答:
1赞
Vlad from Moscow
3/23/2021
#1
在运算符 + 中创建中间对象没有多大意义。
NumberContainer operator+(const NumberContainer& source) const
{
NumberContainer copy{*this};
return copy+=source;
}
像这样定义它
NumberContainer operator+(const NumberContainer& source) const
{
return *(_numObj.num) + *(source._numObj.num);
}
此外,复制构造函数可以定义如下
NumberContainer(const NumberContainer& source) : _numObj{*(source._numObj.num)}
{
std::cout<<"Copy constructor called" << std::endl;
}
评论
0赞
Michel H
3/23/2021
嗨,弗拉德,您是否正在强制从数字转换为 NumberContainer 返回值?这似乎很合适,但正如我之前所说,这是一个代表性的例子,说明类可能比只有一个成员变量要复杂得多。在一般情况下,您如何解决它?
0赞
Vlad from Moscow
3/23/2021
@MichelHeusser 您可以返回一个带支撑的列表,而无需创建中间对象。
下一个:car 类中的复制构造函数
评论
operator+
return NumberContainer(this->number+source.number);