对象初始化列表、深拷贝

对象初始化列表:
构造函数后加 “ :”, 后面接上要初始化的成员,各个成员之间以逗号进行区分

Test(int a, int b): m_a(),m_b(b)
{}

1、对象初始化列表的执行要优先于 构造函数
2、对象的初始化顺序和对象在初始化列表中所在位置无关,和在类中的声明顺序有关

拷贝构造: 类型(const 类名& 变量名)

Test(const Test &obj)     // 拷贝构造函数  赋值构造函数
    {
        m_a = obj.m_a;
        printf ("拷贝构造被调用\n");
    }


Test t = 10;

Test t1 = t;
t1.show();

// 赋值操作   t1已经存在,
t1 = t;    //这里不会调用构造函数    和对象初始化进行区分

// 函数参数是对象的时候,实参到形参的传递会调用拷贝构造 ==> 建议使用引用
void func(Test &obj){}

// 对象作为返回值的时候,也会调用拷贝构造函数 
// ===>  不同的编译对函数返回值处理方式可能不同
Test func()
{
    Test t = 10;
    return t;
}

当类中没有拷贝构造的时候,系统会添加一个拷贝构造,进行 “值” 的复制 ====> 浅拷贝过程
深拷贝:复制的时候连同 堆上的空间一起复制 ====> 自己写
当成员变量中存在指针的时候,要进行深拷贝

Test1(const Test1 &obj)//拷贝构造函数
    {
        m_a = obj.m_a;
        m_b = obj.m_b;
        m_pa = new int;
        *m_pa = *(obj.m_pa);
    }
<think>嗯,用户的问题很具体,聚焦在C++拷贝构造函数初始化匿名对象的场景。从对话历史看,用户之前已经查看了多篇关于拷贝构造函数的资料,包括构造函数调用时机、匿名对象生命周期等内容,但似乎对实际代码示例有更强需求。用户可能正在学习C++深拷贝机制,或者遇到了匿名对象相关的性能问题。ta引用的资料[3]特别提到函数返回匿名对象时的拷贝行为,这应该是个关键线索。我注意到用户上次提问时系统要求“引用段落末尾添加标识”,这次回复需要特别注意规范引用格式。在技术层面,需要区分两个核心场景:匿名对象初始化时的隐式拷贝构造和函数返回时的复制操作。示例设计应包含:1)直接初始化匿名对象的写对比2)返回值优化机制的说明3)浅拷贝陷阱的提醒。特别要注意引用[3]中关于函数返回时拷贝构造与析构的顺序描述。代码示例需要体现匿名对象的瞬时性特点,比如用临时对象初始化对象的场景。考虑到用户可能混淆匿名对象和显式对象的区别,还要在注释中强调生存周期差异。深拷贝示例部分准备用字符串指针,因为引用[5]提到这是经典场景。要不要提移动语义呢?虽然用户没问,但匿名对象本质是右值,不过暂时先专注于拷贝构造,避免信息过载,最后用相关问题来延伸可能更合适。</think> 以下是使用拷贝构造函数初始化匿名对象C++ 代码示例及分析: ```cpp #include <iostream> #include <cstring> using namespace std; class Student { private: char* name; public: // 深拷贝版拷贝构造函数(关键) Student(const Student& other) { name = new char[strlen(other.name) + 1]; strcpy(name, other.name); cout << "拷贝构造函数调用 -> " << name << endl; } // 参数化构造函数 Student(const char* str) { name = new char[strlen(str) + 1]; strcpy(name, str); cout << "参数构造调用 -> " << name << endl; } ~Student() { cout << "析构函数调用 -> " << name << endl; delete[] name; // 释放堆内存 } }; // 返回匿名对象的函数 Student createStudent(const char* name) { return Student(name); // 创建匿名对象 } int main() { // 场景1:显式初始化匿名对象 Student(Student("小明")); // 直接用另一个对象初始化 cout << "----------" << endl; // 场景2:函数返回匿名对象初始化对象 Student s = createStudent("小红"); // ⚠️编译器可能优化掉拷贝 cout << "----------" << endl; return 0; } ``` ### 关键机制分析 1. **匿名对象初始化** 当使用 `Student(Student("小明"))` 时: - 先通过字符串参数构造创建临时对象 - 调用**拷贝构造函数**初始化新匿名对象 - 两个对象立即析构(生命周期仅限该语句) 2. **函数返回匿名对象** 在 `createStudent()` 中: - `return Student(name)` 创建匿名对象 - C++标准允许编译器优化掉拷贝构造(称为RVO优化)[^3] - 未优化时:参数构造 → 拷贝构造(返回时)→ 析构临时对象 ### 输出示例(无编译器优化时) ``` 参数构造调用 -> 小明 拷贝构造函数调用 -> 小明 析构函数调用 -> 小明 析构函数调用 -> 小明 ---------- 参数构造调用 -> 小红 // 函数内创建 拷贝构造函数调用 -> 小红 // 返回时的拷贝 析构函数调用 -> 小红 // 函数内对象析构 ---------- 析构函数调用 -> 小红 // main中对象析构 ``` ### 注意事项 1. **深拷贝必要性** 类内含指针成员时必须实现深拷贝构造函数,否则会导致双删错误[^5] 2. **编译器优化** C++17起强制要求实现返回值优化(RVO),下列情况可能省略拷贝: ```cpp Student s = createStudent("小红"); // 直接构造到目标地址 ``` 3. **生命周期** 匿名对象若不立即使用,会在该语句结束时自动析构[^3] --- ### 相关问题 1. 如何强制编译器禁用拷贝构造函数优化? 2. 移动构造函数如何提升匿名对象初始化效率? 3. 使用 `const Student&` 引用匿名对象会改变其生命周期吗? 4. 在什么情况下匿名对象会导致内存泄漏? [^1]: 示例展示编译器自动生成默认拷贝构造 [^2]: 使用对象初始化对象时触发拷贝构造 [^3]: 函数返回匿名对象时的拷贝构造调用机制 [^4]: 拷贝构造在传值调用时的作用 [^5]: 深拷贝与浅拷贝的实现差异
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值