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

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的完整副本?如果是这样,我想知道这是否是一个好习惯? (我假设当结构大小时,这将创建大量的副本开销)。

有帮助吗?

解决方案

将结构作为参数传递没有错。一切都按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
}

其他提示

是的,这没有错,是的, p 是完整的副本 p1. 。我不会叫 struct 有两个 int很大,但是如果 struct 确实变大了,如果您不需要在功能体中进行更改,则可以考虑通过const参考将其传递:

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

在我回答您的问题之前 (您在这篇文章的结尾找到了),这是您将参数传递给函数的可能性的简要摘要:


1.复制构造的对象(逐个价值):

void cp(point p);

这是逐个价值。临时 point 对象是从任何东西创建和复制构造的 point 您传递的对象 cp. 。一旦执行离开 cp 功能,临时对象被破坏。

请注意,由于该功能在传递给该功能的任何内容的副本上运行,因此您可以修改该本地 point 对象尽可能多地,呼叫者的原始对象不会受到影响。没有办法通过通过传递参数来改变这种行为。


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 ++的另一个功能,具有完全合理的用途。

void cp(point p){
}

凭价值获取

void cp(point *p){
}

通过引用获取

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

在Java中,情况不同。传递对象始终通过参考。

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

您可以考虑通过参考传递对象

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

或成为const参考

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

请参阅避免按值传递对象的可能性。该对象不仅是“复制”,而且是构造的复制。因此,这涉及调用复制构造函数和复制构造函数,如果您的对象是由更多对象组成或得出的。如果可能的话,请通过参考。

void cp(point&p const)const {

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

}

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top