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

8 c++ struct function 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);
}
Run Code Online (Sandbox Code Playgroud)

打印出来的结果是:

1
2
Run Code Online (Sandbox Code Playgroud)

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

CB *_*ley 18

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

void cp(const point& p)
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)


rap*_*ard 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
}
Run Code Online (Sandbox Code Playgroud)

  • 并非所有内容都是通过C++中的值传递的,尽管在C中就是这种情况(没有引用). (2认同)

sta*_*ica 5

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


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

void cp(point p);
Run Code Online (Sandbox Code Playgroud)

这是按值传递的.pointpoint您传入的任何对象创建并复制构造临时对象cp.一旦执行离开cp函数,临时对象就会被销毁.

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


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

void cp(point& p);
Run Code Online (Sandbox Code Playgroud)

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

void cp(const point& p);
Run Code Online (Sandbox Code Playgroud)

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

void cp(point* p);
Run Code Online (Sandbox Code Playgroud)

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

void cp(const point* p);
Run Code Online (Sandbox Code Playgroud)

回答你的问题:

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