用C++返回类的最佳方法
Best Way to Return a Class in C++
我正在为一个项目编写C++向量类,我很难决定如何最好地编写一些方法。在我开始之前,我会说这个类有一个很好的复制构造函数和赋值运算符(这将在一秒钟内相关)。该类有一组静态方法,当我想确保两个参数都没有更改时,这些方法会返回向量,它们具有以下签名:
Vector* Vector::subtract(const Vector* v, const Vector* u)
{
double outX = v->myX - u->myX;
double outY = v->myY - u->myY;
double outZ = v->myZ - u->myZ;
return new Vector(outX, outY, outZ);
}
我遇到的问题是,如果我能帮助的话,我不想返回指针。所以我做了一些测试,并意识到如果我只说
return Vector(outX, outY, outZ)
然后像一样分配结果
Vector foo = Vector::subtract(bar, temp)
它将创建一个副本并运行良好。这就是我的问题所在:我刚刚调用了构造函数两次(本质上),有办法绕过它吗?其次,如果我用这个方法作为另一种方法的论据,比如
foo.multiply(&Vector::subtract(foo, bar), 5)
它还会创建一个副本吗?还是我只是传递了Vector::减法方法中超出范围的指针?
更普遍地说,什么是最好的(或者至少有更好的)方法来做到这一点?
我刚刚调用了构造函数两次(本质上)有没有方法绕过那个?
您听说过退货价值优化吗?您无需执行任何操作。编译器很可能会为您消除副本。现在,如果您使用C++11并且Vector
类管理资源,那么您也可以声明一个移动构造函数,以便在编译器决定不能执行RVO时移动返回值。然而,看起来类只包含3个值,如果是这样的话,复制将和移动一样高效。
&矢量::减去(foo,bar)
&
的作用是什么?那是个错误吗?此外,成员函数未声明为static
,因此语法错误。无论如何,假设subtract
返回了一个副本,它将返回一个副本并将其作为参数传递给multiply
函数。
此外,在另一个注意事项上,Vector* Vector::subtract(const Vector* v, const Vector* u)
会更好地作为Vector* Vector::subtract(const Vector& v, const Vector& u)
,这使得在传递减法等参数时语法更干净。
因此,更改您的代码时,会出现以下情况:
Vector Vector::subtract(const Vector& v, const Vector& u)
{
return Vector(v.myX - u.myX, v.myY - u.myY, v.myZ - u.myZ);
}
向动态分配的对象返回指针/引用从来都不是一条路。显而易见的例子是,如果您的函数被递归调用,谁负责取消分配内存?
我从Scott Meyers的一本书中读到,唯一安全的方法是返回对象本身。IIRC可以帮助编译器消除这些本质上是临时的对象(从一个函数返回到另一个函数,而不将每个对象分配给另一个),其中一种方法是使其匿名(也称为返回值优化,感谢In silico提醒我)。像这样
return Vector(outX, outY, outZ);
与相反
Vector v(outX, outY, outZ);
return v;
所以我为你的减法提出的签名可以归结为:
Vector Vector::subtract(const Vector& v, const Vector& u)
您应该尽可能避免指针,不仅在返回类型中,而且在函数的参数中。尽可能首选引用,必要时使用指针。
如果您更改函数以通过引用获取参数并通过值返回。当在域中有意义时,考虑重载运算符(我认为这里就是这样):
class Vector { ... };
Vector operator+( Vector const& lhs, Vector const& rhs ) {
return Vector( lhs.x+rhs.x, lhs.y+rhs.y, lhs.z+rhs.y );
}
Vector operator*( Vector const& lhs, Vector const& rhs ) { ... }
然后你可以随意连锁操作:
Vector a(...), b(...);
Vector c = (a + b) * c;
现在大多数编译器都会实现所谓的返回值优化(RVO)来解决这个问题。除非真的有必要,否则不应该返回指针,这是对的。话虽如此,您可能应该使用参考资料。总而言之,如果我要写这个方法,我会这样写:
Vector Vector::subtract(const Vector& v, const Vector& u)
{
return Vector(v.myX - u.myX, v.myY - u.myY, v.myZ - u.myZ);
}
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- 在C++中向零方向近似的最佳方法
- 使用不同的CRT将新的C++代码与旧的(二进制)组件隔离开来的最佳方法是什么
- 检测win32服务创建和删除的最佳方法
- 在C++中样板"冷/never_inline"错误处理技术的最佳方法是什么?
- 在 c++ 中对类中的 c 字符串动态数组进行排序的最佳方法是什么?
- 将线程中的数据存储到全局容器的最佳方法?
- 将一系列整数放入类的最佳方法是什么?
- 在派生类中使用基类的私有成员变量的最佳方法
- 在 C++ 中将非指定类型作为参数传递的最佳方法?
- Qt - QVector 和模型视图 - 从列表视图获取自定义类的最佳方法是什么?
- 使用 Git 处理 C++ Visual Studio 2019 解决方案的外部依赖项源代码管理的最佳方法是什么?
- 比较两个节点坐标的最佳方法是什么?
- 在nodejs中使用本机代码的最佳方法是什么?
- 将 pybind11 绑定标记为已弃用的最佳方法
- C++:将向量传递到构造函数以创建成员变量的最佳方法?
- C++中变量混叠的最佳方法
- 读取大文件(>2GB)(文本文件包含以太网数据)并通过不同参数随机访问数据的最佳方法是什么?