将 struct 对象作为参数传递给 C++ 中的函数是一个好习惯吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2724708/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 00:30:05  来源:igfitidea点击:

Is it a good practice to pass struct object as parameter to a function in c++?

c++functionstructoverhead

提问by CB Bailey

I tried an example live below:

我在下面尝试了一个例子:

typedef struct point
{
    int x;
    int y;
} point;

void cp(point p)
{
    cout<<p.x<<endl;
    cout<<p.y<<endl;
}

int main()
{
    point p1;
    p1.x=1;
    p1.y=2;
    cp(p1);
}

The result thats printed out is:

打印出来的结果是:

1
2

which is what I expected. My question is: Does parameter p get the full copy of object p1? If so, I wonder if this is a good practice? (I assumed when the struct gets big in size, this will create a lot of copy overhead).

这正是我所期望的。我的问题是:参数 p 是否获得了对象 p1 的完整副本?如果是这样,我想知道这是否是一个好习惯?(我假设当结构体变大时,这会产生大量的复制开销)。

采纳答案by raph.amiard

There is nothing wrong with passing structs as parameters. Everything is passed by value in C++ so a full copy is indeed made.

将结构作为参数传递并没有错。在 C++ 中一切都是按值传递的,因此确实制作了完整的副本。

The struct you gave in your example is small so it's probably not a problem if you pass it by value. But if you work with bigger data structures, you may want to pass it by reference.

您在示例中提供的结构很小,因此如果按值传递它可能不是问题。但是如果您使用更大的数据结构,您可能希望通过引用传递它。

Beware though, passing by reference means that if you modify the struct inside your function, your original struct will be modified. Be sure to use the const keyword in every case where you don't modify the struct. This will give you an immediate information about if your functions do modify the information or not.

但请注意,通过引用传递意味着如果您修改函数内的结构,您的原始结构将被修改。请务必在不修改结构的每种情况下使用 const 关键字。这将为您提供有关您的功能是否确实修改信息的即时信息。

Your example could be modified to work with references this way :

您的示例可以修改为以这种方式使用引用:

typedef struct point
{
    int x;
    int y;
} point;

void cp(const point& p) // You can know that cp doesn't modify your struct
{
    cout<<p.x<<endl;
    cout<<p.y<<endl;
}

void mod_point(point& p) // You can know that mod_points modifies your struct
{
    p.x += 1;
    p.y += 1;
}

int main()
{
    point p1;
    p1.x=1;
    p1.y=2;
    cp(p1);
    mod_point(p1);
    cp(p1); // will output 2 and 3
}

回答by CB Bailey

Yes, there's nothing wrong with this and yes, pis a complete copy of p1. I wouldn't call a structwith two ints large, but if the structdoes get large and if you don't need to alter it in the function body you could consider passing it by const reference:

是的,这没有任何问题,是的,pp1. 我不会struct用两个ints 来调用 a ,但是如果struct确实变大并且您不需要在函数体中更改它,您可以考虑通过 const 引用传递它:

void cp(const point& p)
{
    // ...
}

回答by stakx - no longer contributing

Before I give an answer to your question(you find it at the end of this post), here's a brief summary of the possibilities you have for passing arguments to a function:

在我回答您的问题之前(您可以在本文末尾找到它),这里简要总结了您将参数传递给函数的可能性:



1. Copy-constructed objects (pass-by-value):

1. 复制构造的对象(传值):

void cp(point p);

This is pass-by-value. A temporary pointobject is created and copy-constructed from whatever pointobject you pass into cp. Once execution leaves the cpfunction, the temporary object is destroyed.

这是传值。一个临时point对象是从point你传入的任何对象中创建和复制构造的cp。一旦执行离开cp函数,临时对象就会被销毁。

Note that because the function operates on a copy of whatever was passed to the function, you can modify that local pointobject as much as you want, the original object of the caller will not be affected. There's no way to change this behaviour with pass-by-value parameters.

请注意,因为该函数对传递给该函数的任何内容的副本进行操作,所以您可以根据需要修改该本地point对象,调用者的原始对象不会受到影响。无法使用按值传递参数更改此行为。



2. References to objects (pass-by-reference):

2. 对象的引用(pass-by-reference):

void cp(point& p);

This is pass-by-reference. The actual object passed to the function is available (and potentially subject to modification) inside the function. If you don't want the function to be able to change the passed-in object, declare the parameter as const point&:

这是传递引用。传递给函数的实际对象在函数内部可用(并且可能会被修改)。如果您不希望该函数能够更改传入的对象,请将参数声明为const point&

void cp(const point& p);


3. Pointers to objects (pass-by-reference):

3. 指向对象的指针(pass-by-reference):

void cp(point* p);

This is also pass-by-reference, with a few subtle differences. One notable difference is that you can pass a null pointer to the function. This is not possible with references, because references mustbe initialized and cannot be reseated afterwards. -- As with references, if you want to disallow cpfrom changing the passed-in point, declare it as const:

这也是传递引用,有一些细微的差异。一个显着的区别是您可以向函数传递一个空指针。这对于引用是不可能的,因为引用必须被初始化并且之后不能被重新设置。-- 与引用一样,如果您想禁止cp更改传入的内容point,请将其声明为 const:

void cp(const point* p);


Answer to your question:

回答你的问题:

Pass-by-value parameters are not inherently bad in any way. Of course, there are types for which copy construction is expensive (e.g. very large or complex objects), or where it has certain side effects (e.g. with std::auto_ptr). In these cases, you should be careful. Otherwise, it's just another feature of C++ which has its perfectly reasonable uses.

传值参数在任何方面都没有本质上的坏处。当然,有些类型的复制构造很昂贵(例如非常大或复杂的对象),或者它有某些副作用(例如 with std::auto_ptr)。在这些情况下,您应该小心。否则,它只是 C++ 的另一个特性,它具有完全合理的用途。

回答by Kasturi

void cp(point p){
}

gets it by value

按值获取

void cp(point *p){
}

gets it by reference

通过引用获取

Just like any other data variable.

就像任何其他数据变量一样。

In java the scenario is different. Passing objects always go by reference.

在 java 中,情况有所不同。传递对象总是通过引用。

回答by Danvil

In you case the point struct is passed "by value" meaning, that the whole structure is copied. For big data types, this can indeed be slow.

在您的情况下,点结构是“按值”传递的,意思是复制整个结构。对于大数据类型,这确实会很慢。

You can consider passing the object by reference

可以考虑通过引用传递对象

void cp(point& p) // p may be altered!

or be const reference

或者是常量引用

void cp(const point& p) // p may not be altered!

回答by Kiran

See the possibilities to avoid passing objects by value. The object is not just 'copied', but is copy constructed. So, this involves calling copy constructor and the chain of copy constructors if your object is composed or derived of more objects. Pass by reference if possible.

查看避免按值传递对象的可能性。该对象不仅是“复制”的,而且是复制构造的。因此,如果您的对象由更多对象组成或派生,则这涉及调用复制构造函数和复制构造函数链。如果可能,通过引用传递。

void cp(point &p const) const {

void cp(point &p const) const {

    cout << p.x << endl;
    cout << p.y << endl;

}

}