我有很多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;
}
将调用vector(myArray)的复制构造函数吗?
答案 0 :(得分:5)
您实际上不需要创建myCloneArray。只需返回myArray,它就会传递一份副本。这是每个编译器的情况。
通常,如果正在返回一个对象,并且它没有通过引用或作为指针返回,则将在类上调用复制构造函数,并将对象作为参数传递。唯一没有发生的情况是复制构造函数是否已被删除,在这种情况下,您发布的代码无论如何都不会编译。
C ++与C#或JAVA之间的不同之处在于,在C#和JAVA中,您实际上是返回一个指针,而不是复制(或移动)堆栈中的对象。如果你这样想,那么语言之间的行为是相同的。
答案 1 :(得分:3)
C ++在类分配方面与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)
; 如果myArray是一个类字段,你可以做得更简单:
vector<double> MyClass::GetMyArray()
{
return myArray;
}