C++浅拷贝

浅拷贝,多个指针指向同一段内存,出现一处指针修改数据,其它指针的数据也发生改变。

1. 面向过程的浅拷贝(C方式)

如下代码:


//下面程序,从键盘获取4个字符串,然后输出到屏幕
int main()
{
    char buf[100];
    char* strArr[4];//长度为4的字符指针数组,分别指向4个字符串
    for (int i = 0; i <4 ; i++)//从键盘获取4个字符串
    {
        cin >> buf;
        strArr[i] = buf;
    }

    for (int i = 0; i < 4; i++)//把4个字符串输出到屏幕
        cout << strArr[i] << " ";

    return 0;
}

1.png

在键盘中输入4个单词:Apple Banana Orange Peach
但是输出的结果却是:Peach Peach Peach Peach
原因如下:

1.png

假设buf的地址为200。第一次从键盘读取Apple,并把200这个地址赋值给strArr[0]。
第二次从键盘读取Banana,并把200这个地址赋值给strArr[1],注意这个地方的问题,由于buf这段内存只有一个,第二次赋值会把第一次的Apple覆盖。
第三次从键盘读取Orange,并把200这个地址赋值给strArr[2],但这时Orange把前面的输入覆盖了。
第四次从键盘读取Pear,并把200这个地址赋值给strArr[3]。但这是Pear把前面的输入覆盖了。
最后输出时strArr[0]到strArr[3]都去地址200处取字符串,就全部都是"Pear"。
这是一个典型的浅拷贝,多个指针指向同一段内存造成的。

2. 面向对象的浅拷贝(类)

下面是一个有问题的类(StringBad类的简化版),只是为了演示浅拷贝的问题


class CStr
{
private:
char* str;//字符串指针
public:
CStr(const char* s)//构造函数,通过s构造一个CStr类对象
{
    str = new char[strlen(s) + 1];//动态创建内存
    strcpy(str,s);//把s的内容复制到str
}
void set(const char* s)//修改字符串的值
{
    delete[]str;//释放原来的内存
    str = new char[strlen(s) + 1];//动态创建内存
    strcpy(str, s);//把s的内容复制到str
}
void show()const
{
    cout << str << endl;
}
};

int main()
{
    CStr s1{"趣字节,有趣的编程"};
    s1.show();//输出s1的内容

    CStr s2 = s1; //把s1赋值给s2
    s2.show();//输出s2的内容

    s2.set("好好学习,天天向上");//修改s2的值
    s2.show();//输出s2的内容
    s1.show();//再输出s1的内容

    return 0;
}
MICROSOFT VISUAL STUDIO 调趣字节,有趣的编程S1最初的值趣字节,有趣的编程S2最初的值好好学习,天天向上S2修改后的值好好学习,天天向上S1没有修改,但值不对了

1.png

第25行,创建一个对象s1,并初始化为"趣字节,有趣的编程";
第28行,创建另一个对象s2,并把s1赋值给s2;
第29行,输出s2的内容,这是是s1赋值的值,这是正确的;
第31行,修改s2的内容,将其改为"好好学习,天天向上";
第32行,输出s2的内容,是修改后的值"好好学习,天天向上",这是正确的;
第33行,输出s1的值,应该是"趣字节,有趣的编程",但实际输出的却是"好好学习,天天向上",这是错误的。
错误的原因也是浅拷贝造成的,具体原因如下图:

1.png

设计并实现一个动态整型数组类Vect,要求: (1)实现构造函数重载,可以根据指定的元素个数动态创建初始值为0的整型数组,或根据指定的内置整型数组动态创建整型数组。 (2)设计拷贝构造函数和析构函数,注意使用深拷贝。 (3)设计存取指定位置的数组元素的公有成员函数,并进行下标越界,若越界则输出“out of boundary”。 (4)设计获取数组元素个数的公有成员函数。 (5)设计用于输出数组元素的公有成员函数,元素之间以空格分隔,最后以换行符结束。 在main函数中按以下顺序操作: (1)根据内置的静态整型数组{1,2,3,4,5}构造数组对象v1,根据输入的整型数构造数组对象v2。 (2)调用Vect的成员函数依次输出v1和v2的所有元素。 (3)输入指定的下标及对应的整型数,设置数组对象v1的指定元素。 (4)根据数组对象v1拷贝构造数组对象v3。 (5)调用Vect的成员函数依次输出v1和v3的所有元素。 设计并实现一个动态整型数组类Vect,要求: (1)实现构造函数重载,可以根据指定的元素个数动态创建初始值为0的整型数组,或根据指定的内置整型数组动态创建整型数组。 (2)设计拷贝构造函数和析构函数,注意使用深拷贝。 (3)设计存取指定位置的数组元素的公有成员函数,并进行下标越界,若越界则输出“out of boundary”。 (4)设计获取数组元素个数的公有成员函数。 (5)设计用于输出数组元素的公有成员函数,元素之间以空格分隔,最后以换行符结束。 在main函数中按以下顺序操作: (1)根据内置的静态整型数组{1,2,3,4,5}构造数组对象v1,根据输入的整型数构造数组对象v2。 (2)调用Vect的成员函数依次输出v1和v2的所有元素。 (3)输入指定的下标及对应的整型数,设置数组对象v1的指定元素。 (4)根据数组对象v1拷贝构造数组对象v3。 (5)调用Vect的成员函数依次输出v1和v3的所有元素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雪星猫宇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值