C++ 对象——程序转换语义

1. 程序转换语义定义

程序转换语义(Copy Elision)是指编译器在特定情况下优化对象的复制和移动操作,直接在目标位置构造对象,从而提高性能并减少资源开销。

2. 定义时初始化

定义时初始化是指在对象创建时通过构造函数直接初始化对象,确保对象在使用前处于有效状态。

示例代码

#include <iostream>
using namespace std;

class X {
public:
    int m_i;
    X(const X& tmpx) {
        m_i = tmpx.m_i;
        cout << "X类的拷贝构造函数被调用" << endl;
    }
    X() {
        m_i = 0;
        cout << "X类的构造函数被调用" << endl;
    }
};

int main() {
    X x0;
    x0.m_i = 15;
    X x1 = x0;
    X x2(x0);
    X x3 = x0; // 分析这一行
    return 0;
}

输出

X类的构造函数被调用
X类的拷贝构造函数被调用
X类的拷贝构造函数被调用
X类的拷贝构造函数被调用

编译器视角

对于 X x3 = x0;

  1. X x3;:分配内存,不调用构造函数。
  2. x3.X::X(x0);:调用拷贝构造函数。

3. 参数的初始化

当对象作为函数参数传递时,C++会根据参数类型决定使用拷贝构造函数或移动构造函数。

示例代码

#include <iostream>
using namespace std;

class X {
public:
    int m_i;
    X(const X& tmpx) {
        m_i = tmpx.m_i;
        cout << "X类的拷贝构造函数被调用" << endl;
    }
    X() {
        m_i = 0;
        cout << "X类的构造函数被调用" << endl;
    }
    ~X() {
        cout << "X类的析构函数被调用" << endl;
    }
};

void func(X tmpx) {
    return;
}

int main() {
    X x0;
    func(x0);
    return 0;
}

输出

X类的构造函数被调用
X类的拷贝构造函数被调用
X类的析构函数被调用
X类的析构函数被调用

编译器视角

func(x0); 中,编译器在 func 函数空间内构造 tmpx 对象,并在返回前析构。

4. 返回值初始化

当函数返回对象时,C++会根据返回类型决定使用拷贝构造函数或移动构造函数。现代C++通常优先使用移动语义。

示例代码

#include <iostream>
using namespace std;

class X {
public:
    int m_i;
    X(const X& tmpx) {
        m_i = tmpx.m_i;
        cout << "X类的拷贝构造函数被调用" << endl;
    }
    X() {
        m_i = 0;
        cout << "X类的构造函数被调用" << endl;
    }
    ~X() {
        cout << "X类的析构函数被调用" << endl;
    }
};

X func() {
    X x0;
    return x0; // 可能会触发拷贝消除
}

int main() {
    X my = func();
    return 0;
}

输出

X类的构造函数被调用
X类的拷贝构造函数被调用
X类的析构函数被调用
X类的析构函数被调用

编译器视角

func 中,编译器可能会优化返回,避免拷贝构造函数的调用。

5. 其他注意事项

  • 移动语义:实现移动构造函数和移动赋值运算符,以充分利用移动语义,减少不必要的拷贝。
  • 资源管理:确保正确实现拷贝和移动语义,避免资源泄漏和双重释放。
  • 异常安全:在实现拷贝和移动构造函数时,确保异常安全,防止在异常发生时导致资源泄漏。

总结

  • 定义时初始化:确保对象在创建时有效。
  • 参数初始化:对象作为参数传递时可能调用拷贝或移动构造函数。
  • 返回值初始化:函数返回对象时优先使用移动构造函数,编译器可能会进行拷贝消除。
  • 注意移动语义和资源管理:确保类正确实现移动和拷贝构造函数。
  • 异常安全:考虑异常影响,确保程序健壮性。
  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值