返回 C++ 等效于 c# 的矢量
Returning Vector in C++ equivalent to c#
我有很多C#代码必须用C++编写。我在C++方面没有太多经验。
我正在使用Visual Studio 2012进行构建。该项目是 C++ 中的静态库(不是 C++/CLI 中的静态库)。
我知道这是一个基本问题,但我一直在阅读,我感到相当困惑。在 C# 代码中,他们在几个地方使用了 double[] 数组,从他们使用它们的方式来看,我看到了替换它们的最佳方法C++就是使用 vector。
C# 中有一些属性返回数组的副本,我想在C++中做同样的事情。
注意:myArray 是 MyClass 的成员。
C#
public double[] MyArray
{
get
{
/*** Some Code Here ***/
double[] myCloneArray= (double[])myArray.Clone();
return myCloneArray;
}
}
我想在C++中完成类似的事情,但尽量减少创建的副本数量。这是正确的吗?
C++
vector<double> MyClass::GetMyArray()
{
/*** Some Code Here ***/
vector<double> myCloneArray= vector<double>(myArray);
return myCloneArray;
}
我只想创建一个 myArray 的副本。由于我没有返回引用,因此我的理解是,在返回myCloneArray时,将创建它的副本。这总是正确的吗?
我想确定一下,所以我在互联网上阅读,但我很困惑,因为有些人说有些编译器不这样做。
我想确保我总是发送副本,而不是相同的向量。我现在正在使用编译器,但最终我的代码也将在其他编译器中构建,所以我需要确保这不是编译器依赖的
这是我能走的最好的方法吗?或者我可以减少代码,像这样:
C++
vector<double> MyClass::GetMyArray()
{
/*** Some Code Here ***/
return myArray;
}
并且向量(myArray)的复制构造函数将被调用?
你实际上不需要创建myCloneArray。只需返回 myArray,它就会传递一个副本。每个编译器都是这种情况。
通常,如果返回一个对象,并且它不是通过引用或作为指针返回的,则将在类上调用复制构造函数,并将对象作为参数传递。唯一不会发生这种情况的情况是复制构造函数已被删除,在这种情况下,您发布的代码无论如何都不会编译。
这在 C++ 和 C# 或 JAVA 之间不同的原因是,在 C# 和 JAVA 中,您实际上是返回一个指针,而不是复制(或移动)堆栈上的对象。如果你这样想,语言之间的行为是相同的。
分配方面与 C# 不同,因为它允许自动分配类,而 C# 要求每次都显式实例化类。
当你用C++写:
std::vector<int> * vec = new std::vector<int>();
C# 中有一个等效项:
List<int> list = new List<int>;
但是,如果您自动分配类:
std::vector<int> vec;
你不可能简单地将其转换为 C#(我的意思是语言结构)。
自动分配的类的行为与简单值的行为更不相同。因此 - 例如 - 当您通过参数将局部变量传递给函数时,它是通过值传递的 - 这意味着,它的值被复制到函数体。同样,当您将参数自动分配的类传递给函数时,它也将被复制到类体中。
当您从函数返回类实例时,也存在类似的机制(按值,就像在您的案例中一样 - 而不是通过指针或引用)。正在创建该类的副本并将其返回给调用方,以便原始类保持不变(无论它在何处以及如何分配)。
不过,C++11有一个问题。从事C++标准工作的人看到,如果你生成一个包含 1000 个元素的向量,然后从函数返回它,这 1000 个元素必须复制到另一个向量,该向量将从函数返回,然后原始向量被销毁。这是一个巨大的不必要的性能损失。
这就是他们引入移动构造函数的原因。在所描述的情况下,从函数返回的副本的构造函数不会复制元素,而只是从局部变量中移动一些字段来访问这些元素(如数组指针)。局部变量紧随其后被销毁,所以没有问题,只复制一个指针 - 而不是 1000 个元素。
这种情况可能发生在现代C++编译器中,但前提是编译器绝对确定不会再使用从中复制数据的向量。因此,如果您返回一个向量(这是一个类字段),编译器将无法调用移动 ctor。
现在,经过一些理论之后,让我们看看你的代码。
vector<double> MyClass::GetMyArray()
{
vector<double> myCloneArray= vector<double>(myArray); // 1
return myCloneArray; // 2
}
首先,你准备 myArray。然后,在 (1) 语句中,您:
- 通过调用
vector<double>(myArray)
显式创建该数组的临时副本; - 然后,您将该临时副本的内容复制到 myCloneArray
- 然后你返回 myCloneArray,它再次被复制到从函数返回的结果。
如果 myArray 是一个类字段,你也可以做得更简单:
vector<double> MyClass::GetMyArray()
{
return myArray;
}
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 什么时候在C++中返回常量引用是个好主意
- 你能重载对象变量名本身返回的内容吗
- 为什么 Serial.println(<char[]>);返回随机字符?
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 如何获取std::result_of函数的返回类型
- QueryWorkingSet总是返回false
- (C++)分析树以计算返回错误值的简单算术表达式
- 访问者访问变体并返回不同类型时出错
- 如何返回一个类的两个对象相加的结果
- OpenInventor从9.8升级到10.4.2后,GLSL纹理返回零
- lower_bound()返回最后一个元素
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- 奇怪的(对我来说)返回声明 - 在谷歌上找不到任何关于它的信息
- 如何取消对nullptr的屏蔽,返回正确的对象
- 奇怪的结构&GCC&clang(void*返回类型)
- 架构决策:返回std::future还是提供回调
- 从python中调用C++函数并获取返回值
- 矩阵向量乘法(cublasDgemv)返回零
- 为什么模板类中的对象不能返回值