Skip to content

C++ ptr move

Posted on:October 24, 2023 at 04:06 AM

三种指针

#include <iostream>
#include <memory>

class MyClass {
public:
    MyClass(int val) : value(val) {}
    void Print() { std::cout << "Value: " << value << std::endl; }

private:
    int value;
};

int main() {
    // 使用 std::unique_ptr 管理对象
    std::unique_ptr<MyClass> uniquePtr = std::make_unique<MyClass>(42);
    uniquePtr->Print(); // 调用对象的成员函数

    // 使用 std::shared_ptr 共享对象
    std::shared_ptr<MyClass> sharedPtr1 = std::make_shared<MyClass>(10);
    std::shared_ptr<MyClass> sharedPtr2 = sharedPtr1;
    sharedPtr1->Print();
    sharedPtr2->Print();

    // 使用 std::weak_ptr 避免循环引用
    std::shared_ptr<MyClass> sharedPtr3 = std::make_shared<MyClass>(99);
    std::weak_ptr<MyClass> weakPtr = sharedPtr3;

    if (auto shared = weakPtr.lock()) {
        std::cout << "Weak Ptr Value: ";
        shared->Print();
    } else {
        std::cout << "Object no longer exists." << std::endl;
    }

    // sharedPtr3 超出作用域后对象会被销毁
    sharedPtr3.reset();

    if (auto shared = weakPtr.lock()) {
        std::cout << "Weak Ptr Value: ";
        shared->Print();
    } else {
        std::cout << "Object no longer exists." << std::endl;
    }

    return 0;
}

左值引用(Lvalue reference)

左值引用是最常见的引用类型,通常用来引用具有标识性的、可修改的对象。 它们使用 & 符号来声明,如 int& lvalueRef = someVariable;。 左值引用可以绑定到左值,即具有标识性的对象,如变量、表达式的结果、函数返回的左值等。 左值引用绑定后,可以修改所引用的对象。 右值引用(Rvalue reference):

右值引用是C++11引入的,用来支持移动语义和完美转发。

它们使用 && 符号来声明,如 int&& rvalueRef = std::move(someVariable);。 右值引用通常绑定到临时对象、字面常量、表达式的结果、以及可以被移动但不能被复制的对象(例如,移动构造函数已定义的对象)。 右值引用支持将资源所有权转移到新对象,从而提高性能,这就是所谓的移动语义。 右值引用还用于实现完美转发,允许函数将参数以其原始类型传递给其他函数

#include <iostream>
#include <string>

// 左值引用参数的函数
void ModifyValue(int& ref) {
    ref += 10;
}

// 右值引用参数的函数,使用移动语义
std::string ConcatenateStrings(std::string&& str1, std::string&& str2) {
    return str1 + str2;
}

int main() {
    int x = 5;
    int& lvalueRef = x; // 左值引用绑定到左值 x
    ModifyValue(lvalueRef);
    std::cout << "x after modification: " << x << std::endl;

    std::string a = "Hello, ";
    std::string b = "world!";
    std::string result = ConcatenateStrings(std::move(a), std::move(b));
    // 使用 std::move() 将 a 和 b 转换为右值引用,支持移动语义
    std::cout << "Concatenated string: " << result << std::endl;

    // 此时 a 和 b 的值可能已被移动,不再有效
    std::cout << "a: " << a << std::endl;
    std::cout << "b: " << b << std::endl;

    return 0;
}

std::move的实现

static_cast实现的