c++ - C++,class,一个返回对象的函数
问题描述
我写了一个名为的类Point
,并想编写一个接受 2Points
并对它们求和的函数。
为什么我应该写如下:
Point SumPoints(Point& p1, Point& p2)
{
Point result(p1->x + p2->x, p1->y + p2->y);
return result;
}
为结果定义一个指针并返回它不是更有效吗?(而不是定义一个新的 Point 'result' 然后在 main 中再次复制它)
另外,我对何时自动调用复制功能有点困惑?每当我输入=
它就会被调用,这是真的吗?
解决方案
result
在这里,按值返回是完全有效的。现代编译器将应用 NRVO命名的返回值优化,这样就不需要复制。如果一个指针由 sum 操作返回,那会更加混乱。
关于您的其他问题(如果我理解正确的话),使用=
并不总是涉及复制。例如,还有一个移动赋值运算符,它只是将rvalue
引用移动到对象中而不是复制它。也有应用复制省略的情况(与上面相同的链接)并允许完全避免复制和移动语义。
在以下示例中,您可以看到编译器大部分都省略了复制或移动(现场演示)
#include <string>
#include <iostream>
#include <iomanip>
struct Point{
Point() = default;
Point(double x, double y):x(x),y(y){}
Point(const Point &p):x(p.x),y(p.y){
std::cout << "copy construct" << std::endl;}
Point(Point&& p):x(std::move(p.x)),y(std::move(p.y)){
std::cout << "move construct" << std::endl;}
Point& operator=(const Point& p){
x = p.x;
y = p.y;
std::cout << "copy assign" << std::endl;
return *this;
}
Point& operator=(Point&& p){
x = std::move(p.x);
y = std::move(p.y);
std::cout << "move assign" << std::endl;
return *this;
}
double x,y;
};
std::ostream& operator<<(std::ostream& out, const Point& p)
{
out << std::setw(5) << p.x << std::setw(5) << p.x << std::flush;
return out;
}
Point operator+(const Point& p1, const Point &p2)
{
return Point(p1.x+p2.x,p1.y+p2.y);
}
Point sum1(const Point& p1, const Point &p2)
{
return Point(p1.x+p2.x,p1.y+p2.y);
}
Point sum2(const Point& p1, const Point &p2)
{
Point result;
result.x = p1.x+p2.x;
result.y = p1.y+p2.y;
return result;
}
int main()
{
Point p1(1,0), p2(0,1);
auto r1 = sum2(p1,p2);
auto r2 = sum1(p1,p2);
auto r3 = r1+r2;
auto r4 = r3; // <- only this calls the copy constructor
std::cout << "r3 = ("<< r3 << ")"<< std::endl;
}
这打印:
copy construct
r3 = ( 2 2)
作为提示,您可以重载+
示例中所示的运算符,以便以更易读的方式编写总和。
推荐阅读
- go - 处理 defer 中的错误
- c# - 尝试使用带有条件的实体/Linq 搜索数据库
- java - 如何在不更改按钮字体的情况下更改 TextArea 的字体?
- python - 有没有办法将 Pandas DataFrame 行中的值列表转换为多列?
- c# - 在 C# 中从 SQL Server 中的多个表中进行选择
- react-native - 元素类型无效:需要一个带有 FlatList 的字符串
- php - 上个月按玩家ID汇总MySQL表中的积分并替换为ONE记录
- asp.net-core - 在 .Net Core 的 UseSpaPrerendering 中将控制器动作输出作为 SupplyData 传递
- asp.net-mvc - SendGrid 在 Azure 应用服务中不起作用
- javascript - Angular8 trackby 没有正确更新