C++;函数中的指针和引用 我是从C/java背景到C++,使用Visual Studio社区2017和大量教程。我不确定编写函数来处理数据向量的正确方法是什么。我应该强制函数使用指针/引用吗?我应该让编译器来解决吗?什么是最佳实践

C++;函数中的指针和引用 我是从C/java背景到C++,使用Visual Studio社区2017和大量教程。我不确定编写函数来处理数据向量的正确方法是什么。我应该强制函数使用指针/引用吗?我应该让编译器来解决吗?什么是最佳实践,c++,function,pointers,memory,vector,C++,Function,Pointers,Memory,Vector,这是我的主要任务,我要求输入向量大小,然后将指向整数值的指针传递给函数,该函数通过一个简单的for循环创建并填充向量值。 然后我将数组传递给另一个执行洗牌的函数 vector<int> intVector(int* count) { vector<int> vi; for (int i = 1; i <= *count; i++) vi.push_back(i); return vi; } vector<int>

这是我的主要任务,我要求输入向量大小,然后将指向整数值的指针传递给函数,该函数通过一个简单的for循环创建并填充向量值。 然后我将数组传递给另一个执行洗牌的函数

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;
}
vector intVector(int*count)
{
向量vi;
对于(int i=1;i begin(),v->end(),默认值为\u random\u engine());
返回*v;
}
int _tmain(int argc,_TCHAR*argv[]
{
整数计数;

cout>count;cout您负责强制(或避免)复制周围的对象

关于你的例子:

  • 您可以避免使用指针,而是使用
    引用
例如:

vector<int>& randVector(vector<int>& v)
{
    shuffle(v->begin(), v->end(), default_random_engine());
    return v;
}

<>对于典型代码的C++传递规则非常简单(尽管显然比没有引用/指针的语言更复杂)。
  • 通常,您更喜欢引用指针,除非传入null实际上是您可以做的事情
  • 更喜欢编写不改变其输入的函数,并按值返回输出
  • 输入应该通过const引用传递,除非它是像整数这样的基元类型,它应该通过值传递
  • 如果您需要就地修改数据,请通过非常量引用传递它
有关更多详细信息,请参阅

结果是,以下是两个函数的“正确”签名:

vector<int> intVector(int count);

void randVector(vector<int> &v);
vector intVector(int计数);
void-randVector(vector&v);
这并没有考虑迭代器,迭代器可能是编写第二个函数的正确“通用”方法,但更高级一些。但是,请参阅
std::shuffle
,它允许您通过利用迭代器随机化任意容器:


<>你提到不必要的复制,我会提到当你按值返回“代码>向量\代码>的东西时,它们永远不应该被复制(我假设你使用C++ 11或更新),它们将被“移动”,这不会有显著的开销。因此,在新的C++代码中,“out参数”(通过引用传递参数以对其进行变异)与旧版本相比明显不受鼓励。如果遇到过时的建议,最好知道。但是,通过引用传递参数(如洗牌或排序)被视为“输入/输出”参数:您希望在适当的位置对其进行变异,并且现有数据很重要,而不是简单地被覆盖。

为什么
vector&randVector(vector*v)
而不是简单地
void randVector(vector&v)
,并通过简单地编写
randVector(vi)来调用它不使用指针,在这里你不需要指针。这是一个很好的点,我也想到了。因为AM传递一个指针到内存位置和操作是在原始对象上执行的,而不是拷贝。返回语句确实是冗余的。然而,我觉得C++和她所认为的最佳实践是不确定的。首先,学习智能指针-
std::unique_ptr
std::shared_ptr
std::weak_ptr
以及
std::make_unique
std::make_shared
,尽量不要使用手动内存管理(原始指针和
new
//code>删除
).@JesperJuhl代码中没有手动内存管理,也不需要智能指针。@Konrad Rudolph我没有说有。我只是想给出一些与指针相关的一般建议。您的代码示例将无法编译(
v->begin(),v->end()的含义是什么)
,当
v
不是指向
向量的指针时。谢谢你的回答。我问编译器是否能帮我解决这个问题的原因之一是因为在网上寻找答案时,我遇到了[Return value optimization](),并有点“惊讶”,可以说,“编译器永远不会为你做任何事情。”-weeell,一般来说不太正确。在现实生活中,优化器压缩了很多抽象,并在上面做了更多的工作。您通常只向客户发送未优化的二进制文件吗?;-)@AleksanderNaumenok如果你更详细地阅读它-你会发现它不适用于你的情况。@Algirdas Preidžius谢谢你,我担心会是这样。你有什么好的来源我可以读到关于这个问题的吗?谢谢你的回复。如果我不得不用更实质的东西来替换int值,比如假设一个Person对象,那么我想将其作为
vector intVector(const Person&p);
@Nir“输入应该通过const引用传递,除非它是像整数这样的基本类型,应该通过值传递”-实际上,即使您正在传递一个结构,也可以通过值来传递它。一旦引入引用,您将强制内存加载/存储(引用实际上只是指针),通过传递值,优化器可能只需将所有内容放入寄存器中,并且在任何情况下,通过引入内存引用,您给常量折叠/传播过程带来了更困难的工作。始终进行基准测试。没有任何东西是黑白的。了解您的编译器。@Jesper Juhl,这是我开始阅读有关编译器和什么的书籍时提到的他们在后台做了,它让我在关于C++的假设上有一个循环。@ JePijull我很清楚这一点,但与那些不确定何时使用引用与指针的人一起进入所有这些细节,为什么返回自由函数的引用很少是正确的,等等,看起来像是大规模的过度。甚至RU。按值传递大小为一个单词或更小的类型的拇指长度不正确:
vector<int> intVector(int count);

void randVector(vector<int> &v);