我在下面试了一个例子:
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的完整副本?如果是这样,我想知道这是一个好习惯吗? (我假设当结构体积变大时,这将产生大量的复制开销)。
答案 0 :(得分:18)
是的,这没有任何问题,是的,p
是p1
的完整副本。我不会用两个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;
}