晚上看C++的书,发现浅拷贝与深拷贝还有一个知识点就是运算符重载.突然豁然开朗.以前在java和C#中那些关于普通值赋值,引用赋值,值传递,引用传递那些只知道结果的原因都清清楚楚了(之前想过,去看java的jdk的但是看到String那个复杂的类就望而兴叹了)
C++浅拷贝与深拷贝:
class num{
public:
num() //默认构造函数
{
n=new int;
}
num(int i)
{
n=new int;
*n=i;
}
~num()//析构函数对象销毁时调用
{
delete n;
}
num(num const &s)//这里是复制构造函数
{
n=new int; //将这行代码注视掉说明该拷贝为浅拷贝否则为深拷贝
*n=s.get();
}
int get()const
{
return *n;
}
void set(int x)
{
*n=x;
}
const num equal(const num&r)
{
*n=r.get();
return *this;
}
const num operator=(const num &r)//这里重载运算符=号
{
return equal(r);
}
private:
int *n;
};
int main(){
num *one=new num(3);
num two;
two.equal(*one);//也可以等价与 two=*one;
cout<<"one:"<<one->get()<<endl;
//delete one;//如果为浅拷贝请注释该行或注释该对象的析构函数delete n;否则程序...
//在这里可以修改two的值试试
cout<<"two:"<<two.get()<<endl;
return 0;
}
那么在java和C#关于int a=1;b=a;b=3;最后b的值为3而a的值还是1这就满足了深拷贝原则:在深层副本中,所有的对象都是重复的,即a将值拷贝到b中b会将a的值复制一份放入内存中.不管a做如何改变b始终是a刚开始拷贝的值.它们所指向的内存的地址是不一样的.
Java code?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
|
那么比如A a=new A(); A c=new A(); a=c; a.x="a"那么c.x值也为a.x这个对象不管那个修改了x值那么它们的值都会修改.这就称为浅拷贝.
总结:在java和C#中如果是用=号赋值的话.如果值非引用的值的话,就进行深拷贝.如果为引用的话就进行浅拷贝.C#支持运算符重载大家有兴趣可以尝试一下.不知道这样用C++概念来理解java和C#是否正确.
推理:String类中的字符串拼装是由(StringPool)深拷贝出来的多个字符串放入内存中最后串起来的特殊类.(纯属个人歪理)欢迎大家拍砖.