函数

时间:2017-07-10 16:13:10

标签: c++ function pointers memory vector

我使用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 ++进行游戏开发。了解记忆和绩效管理对我来说很重要。

2 个答案:

答案 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 ++规则非常简单(尽管显然仍然比没有引用/指针的语言更复杂)。

  • 一般来说,更喜欢对指针的引用,除非传入null实际上是你可以做的事情
  • 更喜欢编写不改变输入的函数,并按值返回输出
  • 输入应该通过const引用传递,除非它是像整数这样的基本类型,应该通过值传递
  • 如果您需要改变数据,请通过非const引用传递

有关详细信息,请参阅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参数”(通过引用传递参数来改变它们)。如果您遇到过时的建议,很高兴知道。但是,通过引用传递类似于混乱或排序的内容被认为是“进/出”参数:您希望将其变异并且现有数据很重要,而不仅仅是被覆盖。