我使用Visual Studio社区2017& amp;来自C#/ Java背景到C ++。大量的教程。我不知道编写函数来处理数据向量的正确方法是什么。我应该强制函数使用指针/引用吗?我应该让编译器对其进行排序吗?什么是最佳做法?
这是我的主要内容,我要求对矢量大小进行输入,然后将指向整数值的指针传递给函数,该函数通过简单的for循环创建和填充带有值的向量。 然后我将数组传递给另一个执行shuffle的函数。
vector<int> intVector(int* count)
{
vector<int> vi;
for (int i = 1; i <= *count; i++)
vi.push_back(i);
return vi;
}
vector<int> &randVector(vector<int> *v)
{
shuffle(v->begin(), v->end(), default_random_engine());
return *v;
}
int _tmain(int argc, _TCHAR* argv[])
{
int count;
cout << "Enter vector array size: ";
cin >> count; cout << endl;
cout << "Vector of integers: " << endl;
vector<int> vi = intVector(&count);
for_each(vi.begin(), vi.end(), [](int i) {cout << i << " ";});
cout << endl;
vi = randVector(&vi);
cout << "Randomized vector of integers: " << endl;
for_each(vi.begin(), vi.end(), [](int i) {cout << i << " ";});
cout << endl;
return 0;
}
所以我的问题是,在我的案例中,避免不必要的复制的最佳做法是什么。我应该关心它吗?我应该依靠编译器为我解决它吗?
我计划在桌面和游戏机上使用C ++进行游戏开发。了解记忆和绩效管理对我来说很重要。
答案 0 :(得分:1)
您负责执行(或避免)周围的对象副本。
关于你的例子:
reference
。如下所示:
vector<int>& randVector(vector<int>& v)
{
shuffle(v->begin(), v->end(), default_random_engine());
return v;
}
请注意,由于您正在使用引用,因此shuffle操作已经在修改randVector
的参数,因此无需返回对它的引用。
根据经验,当您需要传递一个对象并且想要避免可能昂贵的副本时,您可以使用引用:
void function(<const> Object& v)
{
// do_something_with_v
}
答案 1 :(得分:0)
传递典型代码的C ++规则非常简单(尽管显然仍然比没有引用/指针的语言更复杂)。
有关详细信息,请参阅https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rf-conventional。
这样做的结果是,这是您的两个功能的“正确”签名:
vector<int> intVector(int count);
void randVector(vector<int> &v);
这没有考虑迭代器,这可能是写第二个函数的正确“通用”方法,但是更高级。但是,请参阅std::shuffle
,它允许您通过利用迭代器随机化任意容器:http://en.cppreference.com/w/cpp/algorithm/random_shuffle。
由于您提到了不必要的复制,我将提到当您按值返回vector
之类的内容时,不应该复制它们(我假设您使用的是C ++ 11或更新版本)。他们将被“移动”,这没有显着的开销。因此,在较新的C ++代码中,与旧版本相比,显着不鼓励“out参数”(通过引用传递参数来改变它们)。如果您遇到过时的建议,很高兴知道。但是,通过引用传递类似于混乱或排序的内容被认为是“进/出”参数:您希望将其变异并且现有数据很重要,而不仅仅是被覆盖。