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

时间:2010-04-27 20:12:07

标签: c++ function struct overhead

我在下面试了一个例子:

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);
}

打印出的结果是:

1
2

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

6 个答案:

答案 0 :(得分:18)

是的,这没有任何问题,是的,pp1的完整副本。我不会用两个struct大号来调用int,但是如果struct变大,如果你不需要在函数体中改变它,你可以考虑通过它由const引用:

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

答案 1 :(得分:8)

将结构作为参数传递没有任何问题。所有东西都是用C ++中的值传递的,所以确实完整了。

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

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

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

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
}

答案 2 :(得分:5)

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


<强> 1。复制构造的对象(按值传递):

void cp(point p);

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

请注意,因为函数对传递给函数的任何内容的副本进行操作,所以您可以根据需要修改该本地point对象,调用者的原始对象不会受到影响。没有办法用pass-by-value参数改变这种行为。


<强> 2。对象的引用(按引用传递):

void cp(point& p);

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

void cp(const point& p);

第3。指向对象的指针(按引用传递):

void cp(point* p);

这也是传递参考,有一些细微差别。一个值得注意的区别是您可以将空指针传递给该函数。引用无法做到这一点,因为引用必须初始化,之后无法重新引用。 - 与引用一样,如果您想禁止cp更改传入的point,请将其声明为const:

void cp(const point* p);

回答你的问题:

按值传递参数本身并不是坏事。当然,存在复制结构昂贵的类型(例如,非常大或复杂的对象),或者具有某些副作用的类型(例如,使用std::auto_ptr)。在这些情况下,你应该小心。否则,它只是C ++的另一个特性,它具有完全合理的用途。

答案 3 :(得分:0)

void cp(point p){
}

按值获取

void cp(point *p){
}

通过引用获取

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

在java中,场景是不同的。传递对象总是通过引用。

答案 4 :(得分:0)

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

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

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

或是const引用

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

答案 5 :(得分:0)

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

void cp(point&amp; p const)const {

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

}