c++ - C++:两个自定义对象的总和,避免复制构造函数的双重调用
问题描述
在下面的示例中,我有两个类,第一个动态分配一个整数,第二个是第一个类的容器。
当我对两个容器对象 ( operator+()
) 求和时,复制构造函数被调用了两次。在我看来,第二个发生在operator+()
函数的“return”语句期间。
如何优化以避免复制构造函数的第二次调用?
显然,这对于我不想做两个深拷贝的更复杂的应用程序具有代表性,如果逻辑上认为总和只需要创建一个对象(然后返回):
(看起来可能有很多代码,但只有运算符和构造函数才能有效地进行求和。我避免使用析构函数以使其更加混乱)。
主要课程:
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...
};
解决方案
在运算符 + 中创建中间对象没有什么意义。
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;
}
推荐阅读
- c# - 从数据库 c# asp.net mvc core 更改现有应用程序
- javascript - 这个非常简单的javascript代码怎么会崩溃
- ibm-cloud-infrastructure - 从 softlayer slcli 创建专用 vsi 时出错
- php - Laravel 如何处理重复的待办事项?
- sql - 将一张表中的数据合并到第二张表中
- python - 为数组赋值(Python,Numpy)
- javascript - 如何能够禁用 ar js 对象
- r - Forestplot 包中的 forestplot() 中的文本左对齐
- javascript - `setTimeout` 和 `setInterval` 是否总是不适用于背景页面?
- java - 根据对象列表中的某些字段获取最小对象