Abstract:



Brief Introduction of speakers:



This live video highlights, poke here!
This lesson code and handout download, stamp here!






Lvalue and rvalue.
Rvalue references
,
,



·



·



·





int x;
int&& rref = x; // error!
int&& rref = GetTemp(); // okCopy the code






Special function
,



,



,



,



,



,


class Widget { public: Widget(); // Default constructor ~Widget(); // Destructor Widget(const Widget& RHS); // Copy constructor Widget& operator=(const Widget& RHS); // Copy the assignment function Widget(Widget&& RHS); // Move the constructor Widget& operator=(Widget&& RHS); // Move the assignment function private: STD ::string mName; int32_t mCount; };Copy the code



Construction and assignment scenarios occur
,



,



,



,



,



,





// Scenario 0 Widget w1(w0); // Widget w2 = w0; // Scenario 2 void Func(Widget w); Func(w0);Copy the code






Rules by which the compiler generates special functions
,



,





class Widget {
    ...
private:
    Bitmap* pb;
};

Widget::Widget(const Widget& rhs) {
    pb = new Bitmap(*rhs.pb);
}Copy the code






Require the compiler to generate special functions


class Widget { public: Widget(); // Default constructor ~Widget(); // Destructor Widget(const Widget& RHS) = default; Widget& operator=(const Widget& rhs) = default; Widget(Widget&& rhs) = default; Widget& operator=(Widget&& rhs) = default; private: std::string mName; int32_t mCount; };Copy the code



Move and copy functions


Widget::Widget(const Widget& rhs)
    : mName(rhs.mName)
    , mCount(rhs.mCount) {}

Widget& Widget::operator=(const Widget& rhs) {
    mName = rhs.mName;
    mCount = rhs.mCount;
    return *this;
}

Widget::Widget(Widget&& rhs)
    : mName(std::move(rhs.mName))
    , mCount(rhs.mCount) {}

Widget& Widget::operator=(Widget&& rhs) {
    mName = std::move(rhs.mName);
    mCount = rhs.mCount;
    return *this
}Copy the code



Avoid inadvertent movement and change of copy
,



,



,



,





class StringTable { public: StringTable() {} ... Private: STD ::map<int, STD ::string> values; };Copy the code





class StringTable {
public:
    StringTable() {
        makeLogEntry("Creating StringTable object");
    }
    ~StringTable() {
        makeLogEntry("Destroying StringTable object");
    }
private:
    std::map<int, std::string> values;
};Copy the code



Do not move or copy
,



,



,





class Widget {
public:
    ...
private:
    Widget(const Widget&);
    Widget& operator=(const Widget&);
};Copy the code





class Widget {
public:
    Widget(const Widget&) = delete;
    Widget& operator=(const Widget&) = delete;
    Widget(Widget&&) = delete;
    Widget& operator=(Widget&&) = delete;
};Copy the code




Can move and copy functions be virtual?


struct Base {
    virtual ~Base() {}
    virtual Base& operator=(const Base& b);
};

struct Derived: public Base {
    virtual Derived& operator=(const Derived& d);
};Copy the code





int main() {
    Base* p0 = new Derived();
    Base* p1 = new Derived();
    *p0 = *p1;
}Copy the code








struct Derived: public Base {
    virtual Derived& operator=(const Base&);
    virtual Derived& operator=(const Derived&);
};Copy the code








struct Base {
    ...
    Base* Clone() const = 0;
};Copy the code






,



,



,



,






Copy and move base classes correctly


struct Base { Base(): x(0) {} Base(const Base& b): x(b.x) {} Base& operator=(const Base& b) { x = b.x; } int x; }; struct Derived: public Base { Derived(): y(1) {} Derived(const Derived& d): y(d.y) {} Derived& operator=(const Derived& d) { y = d.y; } int y; }; int main() { Derived d0; d0.x = 2; d0.y = 2; Derived d1 = d0; printf("%d %d\n", d1.x, d1.y); //0 2 d1.x = 3; d1 = d0; printf("%d %d\n", d1.x, d1.y); / / 3 2}Copy the code



,



,





Derived::Derived(const Derived& d): Base(d), y(d.y) {}

Derived& Derived::operator=(const Derived& d) {
    Base::operator=(d);
    y = d.y;
}Copy the code




Check whether it is itself before moving or copying


class Widget {
    ...
private:
    Bitmap* pb;
};

Widget& Widget::operator=(const Widget& rhs) {
    delete pb;
    pb = new Bitmap(*rhs.pb);
    return *this;
}Copy the code





Widget& Widget::operator=(const Widget& rhs) { if (this ! = &rhs) { delete pb; pb = new Bitmap(*rhs.pb); } return *this; }Copy the code






Implement exception-safe copy assignment functions.
,



,








class Widget {
    ...
private:
    Bitmap* pb;
};

Widget::Widget(Widget&& rhs) {
    pb = rhs.pb;
    rhs.pb = nullptr;
}

Widget& Widget::operator=(Widget&& rhs) {
    pb = rhs.pb;
    rhs.pb = nullptr;
}

Widget::Widget(const Widget& rhs) {
    pb = new Bitmap(*rhs.pb);
}

Widget& Widget::operator=(const Widget& rhs) {
    Widget tmp(rhs);
    *this = std::move(tmp);
    return *this;
}Copy the code






,



,



Move functions cannot throw exceptions



,



,



,





Widget::Widget(Widget&& rhs) noexcept {
    pb = rhs.pb;
    rhs.pb = nullptr;
}

Widget& Widget::operator=(Widget&& rhs) noexcept {
    pb = rhs.pb;
    rhs.pb = nullptr;
}Copy the code