如何将以下Java代码正确地翻译成C ++?
Vector v;
v = getLargeVector();
...
Vector getLargeVector() {
Vector v2 = new Vector();
// fill v2
return v2;
}
所以这里v
是一个参考。该函数创建一个新的Vector对象并返回对它的引用。很干净。
但是,让我们看看以下C ++镜像转换:
vector<int> v;
v = getLargeVector();
...
vector<int> getLargeVector() {
vector<int> v2;
// fill v2
return v2;
}
现在v
是一个矢量对象,如果我理解正确,v = getLargeVector()
将复制函数返回的向量中的所有元素v
,这可能很贵。此外,在堆栈上创建v2
并返回它将导致另一个副本(但我知道现代编译器可以优化它)。
目前这就是我的工作:
vector<int> v;
getLargeVector(v);
...
void getLargeVector(vector<int>& vec) {
// fill vec
}
但我觉得这不是一个优雅的解决方案。
所以我的问题是:这样做的最佳做法是什么(通过避免不必要的复制操作)?如果可能的话,我想避免正常的指针。到目前为止,我从未使用智能指针,我不知道他们是否可以在这里提供帮助。
答案 0 :(得分:6)
大多数C ++编译器都实现return value optimization,这意味着您可以从函数中有效地返回一个类,而无需复制所有对象的开销。
我还建议您写一下:
vector<int> v(getLargeVector());
这样你就可以复制构造对象而不是默认构造,然后运算符赋值给它。
答案 1 :(得分:3)
void getLargeVector(vector<int>& vec) {
// fill the vector
}
目前是一种更好的方法。使用c ++ 0x,第一种方法的问题在于使用移动操作而不是复制操作。
答案 2 :(得分:2)
可以依赖RVO使这段代码编写简单,但依赖RVO也可以咬你。 RVO是依赖于编译器的功能,但更重要的是,支持RVO的编译器可以根据代码本身禁用RVO。例如,如果您要写:
MyBigObject Gimme(bool condition)
{
if( condition )
return MyBigObject( oneSetOfValues );
else
return MyBigObject( anotherSetOfValues );
}
...那么即使是支持RVO的编译器也无法在此进行优化。在许多其他条件下编译器将无法进行优化,因此通过我计算任何设计依赖于RVO以获得性能或功能的代码。
如果你认为一个函数应该只有一个作业(我只是这样做),那么当你意识到你的代码在设计层被破坏时,你对如何返回一个填充向量的困境变得更加简单。你的函数确实做了两个工作:它实例化向量,然后填充它。即使把所有这些迂回放在一边,然而,更通用的&amp;存在可靠的解决方案而不是依靠RVO。只需编写一个填充任意向量的函数。例如:
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
template<typename Iter> Iter PopulateVector(Iter it, size_t howMany)
{
for( size_t n = 0; n < howMany; ++n )
{
*(it++) = n;
}
return it;
}
int main()
{
vector<int> ints;
PopulateVector(back_inserter(ints), 42);
cout << "The vector has " << ints.size() << " elements" << endl << "and they are..." << endl;
copy(ints.begin(), ints.end(), ostream_iterator<int>(cout, " "));
cout << endl << endl;
static const size_t numOtherInts = 42;
int otherInts[numOtherInts] = {0};
PopulateVector(&otherInts[0], numOtherInts);
cout << "The other vector has " << numOtherInts << " elements" << endl << "and they are..." << endl;
copy(&otherInts[0], &otherInts[numOtherInts], ostream_iterator<int>(cout, " "));
return 0;
}
答案 3 :(得分:1)
为什么要避免正常指针?是因为你不想担心内存管理,还是因为你不熟悉指针语法?
如果您不想担心内存管理,那么智能指针是最好的方法。如果您对指针语法感到不舒服,请使用引用。
答案 4 :(得分:1)
你有最好的解决方案。通过引用传递是处理这种情况的方法。
答案 5 :(得分:0)
听起来你可以用一个班级做到这一点......但这可能是不必要的。
#include <vector>
using std::vector;
class MySpecialArray
{
vector<int> v;
public:
MySpecialArray()
{
//fill v
}
vector<int> const * getLargeVector()
{
return &v;
}
};