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