36、经典问题三

深拷贝与赋值操作符
本文探讨了在C++中何时需要重载赋值操作符以实现深拷贝,解释了深拷贝与浅拷贝的区别,并通过具体代码示例展示了如何正确地实现赋值操作符。同时,文章还讨论了std::string类的行为及其潜在陷阱。

1什么时候需要重载赋值操作符?编译器是否提供默认的赋值操作符?

编译器为每个类默认重载了赋值操作符,默认的赋值操作符仅完成浅拷贝,当需要深拷贝时必须重载赋值操作符,赋值操作符与拷贝构造函数有相同的存在意义(浅拷贝与深拷贝)。 指代了外部资源需要深拷贝

#include <iostream>
#include <string>
using namespace std;
class Test
{
    int* m_pointer;
public:
    Test()
    {
        m_pointer = NULL;
    }
    Test(int i)
    {
        m_pointer = new int(i);
    }
    Test(const Test& obj)
    {

        m_pointer = new int(*obj.m_pointer);     // 申请内存,int类型的值。取的是参数对象pointer指针所指向的堆空间的

       }                                                                      //整形值,将整形值取出来并且复制到新申请的内存空间中去

 
    Test& operator = (const Test& obj)          //注意:返回应用,参数是const类型,不是自赋值,返回当前对象
    {
        if( this != &obj )
        {
            delete m_pointer;
            m_pointer = new int(*obj.m_pointer);
        }   
        return *this;
    }
    void print()
    {
        cout << "m_pointer = " << hex << m_pointer << endl;
    }
    ~Test()
    {
        delete m_pointer;
    }
};
int main()
{
    Test t1 = 1;
    Test t2;    
    t2 = t1;    
    t1.print();
    t2.print();    
    return 0;

}

研究main中的功能,当t2=t1时,浅拷贝,析构函数析构了两次同样的堆空间,释放两次。

完善数组类(无代码)。

重载赋值操作符,必然需要实现深拷贝。

如果一个类中什么都没有,编译器提供什么?

Test();        //默认构造函数

Test(const Test&) //拷贝构造函数

Test& operator= (const Test&);  //重载赋值操作符

~Test();  //析构函数

2关于string的疑问:下面代码输出什么?

    string s="12345";

    const char*p=s.c_str();   //成员函数返回一个字符指针,这个字符指针代表c语言中的写法(只有这条是c的)

    cout<<p<<endl;              //打印12345

    s.append(“abced”)   //末尾插入一个字符串,p成为了野指针

    cout<<p<<endl;            //打印12345,而不是12345abced

改为:

string s="12345";

    const char* p=s.c_str();  

    cout<<s<<endl;            

    s.append(“abced”)   

    cout<<s<<endl;

 //结果是12345  12345abced

原因:因为string对象内部维护了一个指向数据的char*指针( .c_str),这个指针可能在程序运行的过程中发生改变。当向尾部插入一个字符串时,指针发生了改变,重新申请堆空间,指向新的堆空间,而p指向之前的地址,旧的堆空间字符串内部将会释放掉,p指针指向释放的空间,成为野指针。

要抛弃c的编程思想。

3:
   const char* p = "12345";        // c语言的写法 *p
   string s = "" ;
    s.reserve(10);                      //改变大小为10个字节
    // 不要使用 C 语言中的方式操作 C++ 中的字符串
    for(int i=0; i<5; i++)
    {  s[i] = p[i]; }

if(!s.empty())

{   cout << s << endl; }

    return 0;
}

问题分析:c++写C语言的程序。

在for循环之前:

string s 内部维护(m_cstr, m_length=0)->10bytes

for循环之后:

 string 内部维护(m_cstr,m_length=0)->12345+ ( 5bytes)        长度还为0;

改:

    const string p = "12345";              
    string s = "" ;
    s.reserve(10);         //改变大小为10个字节
    s=p;

   cout << s << endl;

   return 0;

在需要进行深拷贝的时候必须重载赋值操作符,赋值操作符合拷贝构造函数 有同等重要的意义,string类通过一个数据空间保存字符数据。string类通过一个成员变量保存当前字符串的长度,c++开发避开C语言的思想。

(SCI维路径规划对比)25年最新五种智能算法优化解决无人机路径巡检维路径规划对比(灰雁算法真菌算法吕佩尔狐阳光生长研究(Matlab代码实现)内容概要:本文档主要介绍了一项关于无人机维路径巡检规划的研究,通过对比2025年最新的五种智能优化算法(包括灰雁算法、真菌算法、吕佩尔狐算法、阳光生长算法等),在复杂维环境中优化无人机巡检路径的技术方案。所有算法均通过Matlab代码实现,并重点围绕路径安全性、效率、能耗和避障能力进行性能对比分析,旨在为无人机在实际巡检任务中的路径规划提供科学依据和技术支持。文档还展示了多个相关科研方向的案例与代码资源,涵盖路径规划、智能优化、无人机控制等多个领域。; 适合人群:具备一定Matlab编程基础,从事无人机路径规划、智能优化算法研究或自动化、控制工程方向的研究生、科研人员及工程技术人员。; 使用场景及目标:① 对比分析新型智能算法在维复杂环境下无人机路径规划的表现差异;② 为科研项目提供可复现的算法代码与实验基准;③ 支持无人机巡检、灾害监测、电力线路巡查等实际应用场景的路径优化需求; 阅读建议:建议结合文档提供的Matlab代码进行仿真实验,重点关注不同算法在收敛速度、路径长度和避障性能方面的表现差异,同时参考文中列举的其他研究案例拓展思路,提升科研创新能力。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值