【发布时间】:2013-07-01 15:27:56
【问题描述】:
我一直假设在 [c++] 中使用 [pass-by-value] 传递变量会复制它们,因此接收这些副本的函数不能更改原始变量的内容。
我猜是因为当参数按值传递时,[copy-constructor]被调用,如果没有被程序员重写,默认的[copy-constructor]是[shallow-copy]而不是[deep -复制]!
所以我的问题是为什么他们称它为按值传递,而在类中有指针的情况下,函数可以访问该指针的引用并可能损坏它。还有这个结论正确吗? “只要在类中有指针,并且您可以按值传递该类的对象作为函数参数,请定义复制构造函数!”
如果这个错误很有名,有人知道这个问题的名称或短语吗?
以下是导致修改列表的代码。此类的对象包含一个 int 成员变量 以及指向节点成员变量列表的指针。
class ComplicatedObject{
public:
ComplicatedObject();
~ComplicatedObject();
//ComplicatedObject(const ComplicatedObject& c); // copy construtor
//ComplicatedObject& operator=(const ComplicatedObject& c); // =operator
int int_member_varialbe_; // an int member variable
void addToList(int d);
void printList();
private:
struct node{
int data;
node* next;
};
node* head_; // points to the beginning of a list (linkedlist of int)
};
下面的代码打印 2。然后打印 2 3 !
Test.cpp:
void myfunction(ComplicatedObject obj){
obj.addToList(3);
obj.int_member_variable_ = 5;
}
int main(void){
ComplicatedObject c_object;
c_object.addToList(2);
c_object.printList(); //prints 2
cout << "int member variable befor passing:";
cout << c-object.int_member_variable_ << endl; //prints 6 (a default value)
myfunction(c_object); //pass-by-value
cout << "int member variable after passing:";
cout << c-object.int_member_variable_ << endl; // prints 6 (not 5)
c_object.printList(); // prints 2 3 ! List get changed!
return 0;
}
【问题讨论】:
-
如果你的类有你浅拷贝的指针,它可以。
-
列表发生变化,因为您正在对对象进行浅拷贝。
-
问题的名称是“Pointers Are Evil”(M. Cline)
-
指针有一个值,默认情况下该值被复制。这个值是另一个值的地址。您可以编写一个
value_ptr<T>智能指针类,默认情况下它会逐个复制(无论是克隆、复制构造还是您拥有的)。至于为什么默认会发生这种情况?好吧,struct和class上的默认operator=行为是在 C++ 从 C 拆分之前确定的。 -
想象一下最糟糕的情况,如果您删除第一个指针然后尝试访问第二个指针会发生什么!顺便说一句,黄金法则是几乎从不使用原始指针。
标签: c++ copy-constructor argument-passing pass-by-value shallow-copy