:::::-/:::/:`-:::. `/::-:::
./::::o. `. `-` `oo:- .` .::o.
`:::o s:` `s.
`s` `-:odh/::::://hs-`
-o :dmdhh.:y: /y.ommdy-
/:` `-:..o -o- :o.`s/o+-
y +- s
-od: o` s`
/mmh` /: ` ` `s
:yo:/. +:`-:+:- .+.
`o. .:::s//:-`
-/-. `-o`
`.// . //.`
::o/:o. ` -/+:-/-
s`-+/o/+:/:--:/s//os:.s``
s /-+-:/ ```` +.:///:+
hsysymdd +hyh+mmm`
+yyo`::. -yys`--.
std::string data_1
:::::-/:::/:`-:::. `/::-:::
./::::o. `. `-` `oo:- .` .::o.
`:::o s:` `s.
`s` `-:odh/::::://hs-`
-o :dmdhh.:y: /y.ommdy-
/:` `-:..o -o- :o.`s/o+-
y +- s
-od: o` s`
/mmh` /: ` ` `s
:yo:/. +:`-:+:- .+.
`o. .:::s//:-`
-/-. `-o`
`.// . //.`
::o/:o. ` -/+:-/-
s`-+/o/+:/:--:/s//os:.s``
s /-+-:/ ```` +.:///:+
hsysymdd +hyh+mmm`
+yyo`::. -yys`--.
std::string data_1
If it were done, when ’tis done, then ’twere well
It were done quickly: if the assassination
Could trammel up the consequence, and catch
With his surcease success; that but this blow
Might be the be-all and the end-all – here,
But here, upon this bank and shoal of time,
We’d jump the life to come. But in these cases
We still have judgment here; that we but teach
Bloody instructions, which, being taught, return
To plague the inventor: this even-handed justice
Commends the ingredients of our poison’d chalice
To our own lips. He’s here in double trust:
First, as I am his kinsman and his subject,
Strong both against the deed; then, as his host,
Who should against his murderer shut the door,
Not bear the knife myself. Besides, this Duncan
Hath borne his faculties so meek, hath been
So clear in his great office, that his virtues
Will plead like angels, trumpet-tongu’d, against
The deep damnation of his taking-off;
And pity, like a naked new-born babe,
Striding the blast, or heaven’s Cherubins, hors’d
Upon the sightless couriers of the air,
Shall blow the horrid deed in every eye,
That tears shall drown the wind. I have no spur
To prick the sides of my intent, but only
Vaulting ambition, which o’erleaps itself
And falls on the other.
std::string data_2
:::::-/:::/:`-:::. `/::-:::
./::::o. `. `-` `oo:- .` .::o.
`:::o s:` `s.
`s` `-:odh/::::://hs-`
-o :dmdhh.:y: /y.ommdy-
/:` `-:..o -o- :o.`s/o+-
y +- s
-od: o` s`
/mmh` /: ` ` `s
:yo:/. +:`-:+:- .+.
`o. .:::s//:-`
-/-. `-o`
`.// . //.`
::o/:o. ` -/+:-/-
s`-+/o/+:/:--:/s//os:.s``
s /-+-:/ ```` +.:///:+
hsysymdd +hyh+mmm`
+yyo`::. -yys`--.
:::::-/:::/:`-:::. `/::-:::
./::::o. `. `-` `oo:- .` .::o.
`:::o s:` `s.
`s` `-:odh/::::://hs-`
-o :dmdhh.:y: /y.ommdy-
/:` `-:..o -o- :o.`s/o+-
y +- s
-od: o` s`
/mmh` /: ` ` `s
:yo:/. +:`-:+:- .+.
`o. .:::s//:-`
-/-. `-o`
`.// . //.`
::o/:o. ` -/+:-/-
s`-+/o/+:/:--:/s//os:.s``
s /-+-:/ ```` +.:///:+
hsysymdd +hyh+mmm`
+yyo`::. -yys`--.
std::string data_1
If it were done, when ’tis done, then ’twere well
It were done quickly: if the assassination
Could trammel up the consequence, and catch
With his surcease success; that but this blow
Might be the be-all and the end-all – here,
But here, upon this bank and shoal of time,
We’d jump the life to come. But in these cases
We still have judgment here; that we but teach
Bloody instructions, which, being taught, return
To plague the inventor: this even-handed justice
Commends the ingredients of our poison’d chalice
To our own lips. He’s here in double trust:
First, as I am his kinsman and his subject,
Strong both against the deed; then, as his host,
Who should against his murderer shut the door,
Not bear the knife myself. Besides, this Duncan
Hath borne his faculties so meek, hath been
So clear in his great office, that his virtues
Will plead like angels, trumpet-tongu’d, against
The deep damnation of his taking-off;
And pity, like a naked new-born babe,
Striding the blast, or heaven’s Cherubins, hors’d
Upon the sightless couriers of the air,
Shall blow the horrid deed in every eye,
That tears shall drown the wind. I have no spur
To prick the sides of my intent, but only
Vaulting ambition, which o’erleaps itself
And falls on the other.
std::string data_2
:::::-/:::/:`-:::. `/::-:::
./::::o. `. `-` `oo:- .` .::o.
`:::o s:` `s.
`s` `-:odh/::::://hs-`
-o :dmdhh.:y: /y.ommdy-
/:` `-:..o -o- :o.`s/o+-
y +- s
-od: o` s`
/mmh` /: ` ` `s
:yo:/. +:`-:+:- .+.
`o. .:::s//:-`
-/-. `-o`
`.// . //.`
::o/:o. ` -/+:-/-
s`-+/o/+:/:--:/s//os:.s``
s /-+-:/ ```` +.:///:+
hsysymdd +hyh+mmm`
+yyo`::. -yys`--.
:::::-/:::/:`-:::. `/::-:::
./::::o. `. `-` `oo:- .` .::o.
`:::o s:` `s.
`s` `-:odh/::::://hs-`
-o :dmdhh.:y: /y.ommdy-
/:` `-:..o -o- :o.`s/o+-
y +- s
-od: o` s`
/mmh` /: ` ` `s
:yo:/. +:`-:+:- .+.
`o. .:::s//:-`
-/-. `-o`
`.// . //.`
::o/:o. ` -/+:-/-
s`-+/o/+:/:--:/s//os:.s``
s /-+-:/ ```` +.:///:+
hsysymdd +hyh+mmm`
+yyo`::. -yys`--.
std::string data_1
If it were done, when ’tis done, then ’twere well
It were done quickly: if the assassination
Could trammel up the consequence, and catch
With his surcease success; that but this blow
Might be the be-all and the end-all – here,
But here, upon this bank and shoal of time,
We’d jump the life to come. But in these cases
We still have judgment here; that we but teach
Bloody instructions, which, being taught, return
To plague the inventor: this even-handed justice
Commends the ingredients of our poison’d chalice
To our own lips. He’s here in double trust:
First, as I am his kinsman and his subject,
Strong both against the deed; then, as his host,
Who should against his murderer shut the door,
Not bear the knife myself. Besides, this Duncan
Hath borne his faculties so meek, hath been
So clear in his great office, that his virtues
Will plead like angels, trumpet-tongu’d, against
The deep damnation of his taking-off;
And pity, like a naked new-born babe,
Striding the blast, or heaven’s Cherubins, hors’d
Upon the sightless couriers of the air,
Shall blow the horrid deed in every eye,
That tears shall drown the wind. I have no spur
To prick the sides of my intent, but only
Vaulting ambition, which o’erleaps itself
And falls on the other.
std::string data_2
std::string data_1
If it were done, when ’tis done, then ’twere well
It were done quickly: if the assassination
Could trammel up the consequence, and catch
With his surcease success; that but this blow
Might be the be-all and the end-all – here,
But here, upon this bank and shoal of time,
We’d jump the life to come. But in these cases
We still have judgment here; that we but teach
Bloody instructions, which, being taught, return
To plague the inventor: this even-handed justice
Commends the ingredients of our poison’d chalice
To our own lips. He’s here in double trust:
First, as I am his kinsman and his subject,
Strong both against the deed; then, as his host,
Who should against his murderer shut the door,
Not bear the knife myself. Besides, this Duncan
Hath borne his faculties so meek, hath been
So clear in his great office, that his virtues
Will plead like angels, trumpet-tongu’d, against
The deep damnation of his taking-off;
And pity, like a naked new-born babe,
Striding the blast, or heaven’s Cherubins, hors’d
Upon the sightless couriers of the air,
Shall blow the horrid deed in every eye,
That tears shall drown the wind. I have no spur
To prick the sides of my intent, but only
Vaulting ambition, which o’erleaps itself
And falls on the other.
std::string data_2
:::::-/:::/:`-:::. `/::-:::
./::::o. `. `-` `oo:- .` .::o.
`:::o s:` `s.
`s` `-:odh/::::://hs-`
-o :dmdhh.:y: /y.ommdy-
/:` `-:..o -o- :o.`s/o+-
y +- s
-od: o` s`
/mmh` /: ` ` `s
:yo:/. +:`-:+:- .+.
`o. .:::s//:-`
-/-. `-o`
`.// . //.`
::o/:o. ` -/+:-/-
s`-+/o/+:/:--:/s//os:.s``
s /-+-:/ ```` +.:///:+
hsysymdd +hyh+mmm`
+yyo`::. -yys`--.
std::string data_1
std::string data_2
:::::-/:::/:`-:::. `/::-:::
./::::o. `. `-` `oo:- .` .::o.
`:::o s:` `s.
`s` `-:odh/::::://hs-`
-o :dmdhh.:y: /y.ommdy-
/:` `-:..o -o- :o.`s/o+-
y +- s
-od: o` s`
/mmh` /: ` ` `s
:yo:/. +:`-:+:- .+.
`o. .:::s//:-`
-/-. `-o`
`.// . //.`
::o/:o. ` -/+:-/-
s`-+/o/+:/:--:/s//os:.s``
s /-+-:/ ```` +.:///:+
hsysymdd +hyh+mmm`
+yyo`::. -yys`--.
std::string data_1
std::string data_2
:::::-/:::/:`-:::. `/::-:::
./::::o. `. `-` `oo:- .` .::o.
`:::o s:` `s.
`s` `-:odh/::::://hs-`
-o :dmdhh.:y: /y.ommdy-
/:` `-:..o -o- :o.`s/o+-
y +- s
-od: o` s`
/mmh` /: ` ` `s
:yo:/. +:`-:+:- .+.
`o. .:::s//:-`
-/-. `-o`
`.// . //.`
::o/:o. ` -/+:-/-
s`-+/o/+:/:--:/s//os:.s``
s /-+-:/ ```` +.:///:+
hsysymdd +hyh+mmm`
+yyo`::. -yys`--.
data1
This is very long text. It takes linear time to copy it.
data2
Some more long text that cannot be quickly copied.
temporary
void swap(some_t& data1, some_t& data2) {
some_t temporary = data1;
data1 = data2;
data2 = temporary;
}
This is very long text. It takes linear time to copy it.
data1
This is very long text. It takes linear time to copy it.
data2
Some more long text that cannot be quickly copied.
temporary
void swap(some_t& data1, some_t& data2) {
some_t temporary = data1;
data1 = data2;
data2 = temporary;
}
This is very long text. It takes linear time to copy it.
Some more long text that cannot be quickly copied.
data1
data2
Some more long text that cannot be quickly copied.
temporary
void swap(some_t& data1, some_t& data2) {
some_t temporary = data1;
data1 = data2;
data2 = temporary;
}
This is very long text. It takes linear time to copy it.
Some more long text that cannot be quickly copied.
This is very long text. It takes linear time to copy it.
This is very long text. It takes linear time to copy it.
data1
data2
temporary
void swap(some_t& data1, some_t& data2) {
some_t temporary = data1;
data1 = data2;
data2 = temporary;
}
This is very long text. It takes linear time to copy it.
Some more long text that cannot be quickly copied.
This is very long text. It takes linear time to copy it.
Some more long text that cannot be quickly copied.
void swap(some_t& data1, some_t& data2) {
some_t temporary = std::move(data1);
data1 = std::move(data2);
data2 = std::move(temporary);
}
void swap(some_t& data1, some_t& data2) {
some_t temporary = data1;
data1 = data2;
data2 = temporary;
}
presumably > O(1)
presumably = O(1)
ClassName c1;
ClassName c2{c1};
ClassName c3 = c1;
Copy/Move
Construction
Copy/Move
Assignment
ClassName c1;
ClassName c2;
c2 = c1;
Has identity | No identity |
---|---|
lvalue | rvalue |
pre-C++11
type variable object.member assign = ment ++preincrement ar[indexing] ...
42 comp < arison &address postincrement++ this ...
lvalue = ...
... = rvalue
rvalue = ...
(if no const)
Has identity | No identity |
---|---|
lvalue | rvalue |
Can move?
No???
Yes???
Has identity | No identity | |
---|---|---|
Cannot move | lvalue | |
Can move | rvalue |
Has identity | No identity | |
---|---|---|
Cannot move | lvalue | ---------- |
Can move | xvalue | prvalue |
xvalue - expiring value
prvalue - pure rvalue
xvalue - expiring value
prvalue - pure rvalue
glvalue - generalized lvalue
Has identity | No identity | |
---|---|---|
Cannot move | lvalue | ---------- |
Can move | xvalue | prvalue |
glvalue
rvalue
class Array {
private:
int* data;
public:
explicit Array(size_t capacity) :
data{new int[capacity]}
{
}
~Array() {
delete[] data;
}
//...
};
Array ar1{3};
class Array {
private:
int* data;
public:
explicit Array(size_t capacity) :
data{new int[capacity]}
{
}
~Array() {
delete[] data;
}
//...
};
Array ar1{3};
Array ar2 = ar1;
class Array {
private:
int* data;
public:
explicit Array(size_t capacity) :
data{new int[capacity]}
{
}
// implicitly-generated
Array(const Array&) = default;
Array(const Array& other) :
data{other.data}
{ // shallow copy
}
~Array() {
delete[] data;
}
//...
};
Array ar1{3};
Array ar2 = ar1;
class Array {
private:
int* data;
int capacity;
public:
explicit Array(size_t capacity) :
data{new int[capacity]},
capacity{capacity}
{
}
Array(const Array& other) :
data{new int[other.capacity]},
capacity{other.capacity}
{ // deep copy
std::copy_n(other.data, capacity, data);
}
~Array() {
delete[] data;
}
//...
};
Array ar1{3};
Array ar2 = ar1;
class ClassName {
T1 member1;
T2 member2;
T3 member3;
// ...
TN memberN;
// copy constructor
ClassName(const ClassName&);
// defaulted copy constructor
ClassName(const ClassName&) = default;
ClassName(const ClassName& other) :
member1{other.member1},
member2{other.member2},
member3{other.member3},
// ...
memberN{other.memberN}
{
}
// deleted copy constructor
ClassName(const ClassName&) = delete;
};
ClassName(const ClassName&);
void f(ClassName byValue);
ClassName g();
ClassName h() {
ClassName obj;
// if no elision and not movable
ClassName obj1 = g();
ClassName obj2{obj};
f(obj);
return obj; // unless movable
}
class ClassName {
T1 member1;
T2 member2;
T3 member3;
// ...
TN memberN;
// copy constructor
ClassName(const ClassName&);
// defaulted copy constructor
ClassName(const ClassName&) = default;
ClassName(const ClassName& other) :
member1{other.member1},
member2{other.member2},
member3{other.member3},
// ...
memberN{other.memberN}
{
}
// deleted copy constructor
ClassName(const ClassName&) = delete;
};
ClassName(const ClassName&);
// if has move constructor
Classname obj1 = lvalue;
// otherwise
Classname obj2 = glvalue;
Has identity | |
---|---|
Cannot move | lvalue |
Can move | xvalue |
glvalue
ClassName func() {
return prvalue;
}
func();
if returning prvalue
T f() {
return T{};
}
T x = T{T{f()}};
T x = T{T{T{}}};
T x = T{T{}};
T x = T{};
T x{};
if initializer is a prvalue and of same type
(and move)
Has identity | No identity | |
---|---|---|
Cannot move | lvalue | ---------- |
Can move | xvalue | prvalue |
glvalue
rvalue
(and move)
no side effects
in copy and move constructors
class Array {
private:
int* data;
int capacity;
public:
explicit Array(size_t capacity) :
data{new int[capacity]},
capacity{capacity}
{
}
Array(const Array& other) :
data{new int[other.capacity]},
capacity{other.capacity}
{ // deep copy
std::copy_n(other.data, capacity, data);
}
Array& operator=(const Array& other) {
if (this != &other) {
int* newData = new int[other.capacity];
std::copy_n(other.data, other.capacity, newData);
delete[] data;
capacity = other.capacity;
data = newData;
}
return *this;
}
~Array() {
delete[] data;
}
//...
};
Array ar1{3};
Array ar2{5};
ar2 = ar1;
class ClassName {
T1 member1;
T2 member2;
T3 member3;
// ...
TN memberN;
// copy assignment operator
ClassName& operator=(const ClassName&);
// defaulted copy assignment operator
ClassName& operator=(const ClassName&) = default;
ClassName& operator=(const ClassName& other)
{
member1 = other.member1;
member2 = other.member2;
member3 = other.member3;
// ...
memberN = other.memberN;
}
// deleted copy assignment operator
ClassName(const ClassName&) = delete;
};
ClassName& operator=(const ClassName&);
ClassName obj;
// if has mv asgn op
obj = lvalue;
// otherwise
obj = glvalue;
ClassName& operator=(ClassName); // copy and swap idiom
Has identity | |
---|---|
Cannot move | lvalue |
Can move | xvalue |
glvalue
char* concat(const char* str1, const char* str2) {
size_t len1 = strlen(str1);
size_t len2 = strlen(str2);
size_t len = len1 + len2 + 1;
char* result = new char[len];
strcpy(result, str1);
strcpy(result + len1, str2);
result[len - 1] = '\0';
return result;
}
void user() {
const char* str = concat("Hello ", "World!");
printMessage(str);
} // leak
size_t GetClipboardSize();
void GetClipboard(char* const);
char* const getClipboard() {
size_t len = GetClipboardSize();
static char* const contents{};
delete[] contents;
contents = new char[len];
GetClipboard(contents);
return contents;
}
void user() {
auto contents = GetClipboard();
printMessage(contents);
delete[] contents; // double del
}
char* concat(const char* str1, const char* str2) {
size_t len1 = strlen(str1);
size_t len2 = strlen(str2);
size_t len = len1 + len2 + 1;
char* result = new char[len];
strcpy(result, str1);
strcpy(result + len1, str2);
result[len - 1] = '\0';
return result;
}
void user() {
const char* str = concat("Hello ", "World!");
printMessage(str);
delete[] str;
}
size_t GetClipboardSize();
void GetClipboard(char* const);
char* const getClipboard() {
size_t len = GetClipboardSize();
static char* const contents{};
delete[] contents;
contents = new char[len];
GetClipboard(contents);
return contents;
}
void user() {
printMessage(GetClipboard());
}
#include <string>
void user() {
printMessage(std::string{"Hello "} + "World!");
// printMessage("Hello " "World!");
// using namespace std::string_literals;
// printMessage("Hello "s + "World!");
}
void user() {
printMessage(GetClipboard());
}
char* concat(const char* str1, const char* str2) {
size_t len1 = strlen(str1);
size_t len2 = strlen(str2);
size_t len = len1 + len2 + 1;
char* result = new char[len];
strcpy(result, str1);
strcpy(result + len1, str2);
result[len - 1] = '\0';
return result;
}
size_t GetClipboardSize();
void GetClipboard(char* const);
std::string getClipboard() {
size_t len = GetClipboardSize();
std::string contents;
contents.resize(len);
GetClipboard(contents.data());
return contents;
}
data1
Some more long text that cannot be quickly copied.
resposibility
to clean up
data2
data1
Some more long text that cannot be quickly copied.
resposibility
to clean up
data2
class Array {
private:
int* data;
int capacity;
public:
explicit Array(size_t capacity) :
data{new int[capacity]},
capacity{capacity}
{
}
Array(Array&& other) noexcept :
data{other.data},
capacity{other.capacity}
{
other.data = nullptr;
other.capacity = 0;
}
~Array() {
delete[] data;
}
//...
};
Array ar1{3};
Array ar2 = std::move(ar1);
class Array {
private:
int* data;
int capacity;
public:
explicit Array(size_t capacity) :
data{new int[capacity]},
capacity{capacity}
{
}
Array(Array&& other) noexcept :
data{std::exchange(other.data, nullptr)},
capacity{std::exchange(other.capacity, 0)}
{
}
~Array() {
delete[] data;
}
//...
};
Array ar1{3};
Array ar2 = std::move(ar1);
class Array {
private:
int* data;
int capacity;
public:
explicit Array(size_t capacity) :
data{new int[capacity]},
capacity{capacity}
{
}
Array(Array&& other) noexcept :
data{std::exchange(other.data, nullptr)},
capacity{std::exchange(other.capacity, 0)}
{
}
~Array() {
delete[] data;
}
//...
};
Array ar1{3};
Array ar2 = std::move(ar1);
template <typename T>
std::remove_reference_t<T>&& move(T&& arg) {
return static_cast<remove_reference_t<T>&&>(arg);
}
class ClassName {
T1 member1;
T2 member2;
T3 member3;
// ...
TN memberN;
// move constructor
ClassName(ClassName&&);
// defaulted move constructor
ClassName(ClassName&&) = default;
ClassName(ClassName&& other) :
member1{std::move(other.member1)},
member2{std::move(other.member2)},
member3{std::move(other.member3)},
// ...
memberN{std::move(other.memberN)}
{
}
// deleted move constructor
ClassName(ClassName&&) = delete;
};
ClassName(ClassName&&);
void f(ClassName byValue);
ClassName g();
ClassName g() {
ClassName obj;
ClassName obj1 = g(); // if no elision
ClassName obj2{std::move(obj)};
f(std::move(obj));
return obj;
}
class ClassName {
T1 member1;
T2 member2;
T3 member3;
// ...
TN memberN;
// move constructor
ClassName(ClassName&&);
// defaulted move constructor
ClassName(ClassName&&) = default;
ClassName(ClassName&& other) :
member1{std::move(other.member1)},
member2{std::move(other.member2)},
member3{std::move(other.member3)},
// ...
memberN{std::move(other.memberN)}
{
}
// deleted move constructor
ClassName(ClassName&&) = delete;
};
ClassName(ClassName&&);
Classname obj = xvalue
// move elision if prvalue
Has identity | |
---|---|
Cannot move | lvalue |
Can move | xvalue |
glvalue
class Array {
private:
int* data;
int capacity;
public:
explicit Array(size_t capacity) :
data{new int[capacity]},
capacity{capacity}
{
}
Array(Array&& other) noexcept :
data{std::exchange(other.data, nullptr)},
capacity{std::exchange(other.capacity, 0)}
{
}
Array& operator=(Array&& other) noexcept
{
data = std::exchange(other.data, nullptr);
capacity = std::exchange(other.capacity, 0);
}
~Array() {
delete[] data;
}
//...
};
Array ar1{3};
Array ar2{5};
ar2 = std::move(ar1);
class ClassName {
T1 member1;
T2 member2;
T3 member3;
// ...
TN memberN;
// move assignment operator
ClassName& operator=(const ClassName&);
// defaulted move assignment operator
ClassName& operator=(ClassName&&) = default;
ClassName& operator=(ClassName&& other)
{
member1 = std::move(other.member1);
member2 = std::move(other.member2);
member3 = std::move(other.member3);
// ...
memberN = std::move(other.memberN);
}
// deleted move assignment operator
ClassName(ClassName&&) = delete;
};
ClassName& operator=(ClassName&&);
ClassName& operator=(ClassName); // copy and swap idiom
Classname obj = xvalue
// move elision if prvalue
Has identity | |
---|---|
Cannot move | lvalue |
Can move | xvalue |
glvalue
obj = value;
xvalue
prvalue
lvalue
Has identity | No identity | |
---|---|---|
Cannot move | lvalue | ---------- |
Can move | xvalue | prvalue |
glvalue
rvalue
constructor/
assignment operator
constructor/
assignment operator
elision/
assignment operator
Basic exception guarantee - valid, unspecified state; invariants maintained
No exception guarantee - undefined state
Array& operator=(const Array& other)
{
if (this == &other) return *this;
delete[] data;
data = new int[other.capacity];
capacity = other.capacity;
std::copy_n(other.data, capacity, data);
return *this;
}
Array& operator=(const Array& other)
{
if (this == &other) return *this;
delete[] data;
capacity = 0;
data = new int[other.capacity];
capacity = other.capacity;
std::copy_n(other.data, capacity, data);
return *this;
}
Nothrow exception guarantee - cannot fail
Strong exception guarantee - previous state restored
Array& operator=(const Array& other) {
if (this != &other) {
int* newData = new int[other.capacity];
std::copy_n(other.data, other.capacity, newData);
delete[] data;
capacity = other.capacity;
data = newData;
}
return *this;
}
Array& operator=(Array&& other) noexcept {
data = std::exchange(other.data, nullptr);
capacity = std::exchange(other.capacity, 0);
}
ClassName& operator=(ClassName);
...
Array(const Array& other) :
data{new int[other.capacity]},
capacity{other.capacity}
{
std::copy_n(other.data, capacity, data);
}
Array& operator=(const Array& other) {
capacity = other.capacity;
delete[] data;
data = new int[capacity];
std::copy_n(other.data, capacity, data);
return *this;
}
...
Problems:
ClassName& operator=(ClassName);
...
Array(const Array& other) :
data{new int[other.capacity]},
capacity{other.capacity}
{
std::copy_n(other.data, capacity, data);
}
Array& operator=(const Array& other) {
if (this != &other) {
capacity = other.capacity;
delete[] data;
data = new int[capacity];
std::copy_n(other.data, capacity, data);
}
return *this;
}
...
Problems:
ClassName& operator=(ClassName);
...
Array(const Array& other) :
data{new int[other.capacity]},
capacity{other.capacity}
{
std::copy_n(other.data, capacity, data);
}
Array& operator=(const Array& other) {
if (this != &other) {
capacity = other.capacity;
delete[] data;
data = new int[capacity];
std::copy_n(other.data, capacity, data);
}
return *this;
}
...
Problems:
ClassName& operator=(ClassName);
...
Array(const Array& other) :
data{new int[other.capacity]},
capacity{other.capacity}
{
std::copy_n(other.data, capacity, data);
}
Array& operator=(const Array& other) {
if (this != &other) {
int* newData = new int[other.capacity];
std::copy_n(other.data, other.capacity, newData);
delete[] data;
capacity = other.capacity;
data = newData;
}
return *this;
}
...
Problems:
ClassName& operator=(ClassName);
...
Array(const Array& other) :
data{new int[other.capacity]},
capacity{other.capacity}
{
std::copy_n(other.data, capacity, data);
}
Array& operator=(const Array& other) {
if (this != &other) {
int* newData = new int[other.capacity];
std::copy_n(other.data, other.capacity, newData);
delete[] data;
capacity = other.capacity;
data = newData;
}
return *this;
}
...
Problems:
ClassName& operator=(ClassName);
Array(const Array& other) :
data{new int[other.capacity]},
capacity{other.capacity}
{
std::copy_n(other.data, capacity, data);
}
Array(Array&& other) noexcept :
data{std::exchange(other.data, nullptr)},
capacity{std::exchange(other.capacity, 0)}
{
}
Array& operator=(const Array& other) {
if (this != &other) {
int* newData = new int[other.capacity];
std::copy_n(other.data, other.capacity, newData);
delete[] data;
capacity = other.capacity;
data = newData;
}
return *this;
}
Array& operator=(Array&& other) noexcept {
data = std::exchange(other.data, nullptr);
capacity = std::exchange(other.capacity, 0);
}
ClassName& operator=(ClassName);
Array() :
data{nullptr},
capacity{0}
{
}
Array(const Array& other) :
data{new int[other.capacity]},
capacity{other.capacity}
{
std::copy_n(other.data, capacity, data);
}
Array(Array&& other) noexcept : Array{} {
swap(*this, other);
}
Array& operator=(Array other) {
swap(*this, other);
return *this;
}
friend void swap(Array& lhs, Array& rhs) noexcept {
using std::swap; // ADL
swap(lhs.capacity, rhs.capacity);
swap(lhs.data, rhs.data);
}
If a class has a user-defined or deleted [any of the below]:
It should have them all user-defined.
If a class doesn't deal with ownership, it shouldn't have a user-defined or deleted [any of the above].
copy constructor
copy assignment operator
move constructor
move assignment operator
destructor
#include <type_traits>
std::is_copy_constructible_v<T>
std::is_trivially_copy_constructible_v<T>
std::is_nothrow_copy_constructible_v<T>
std::is_move_constructible_v<T>
std::is_trivially_move_constructible_v<T>
std::is_nothrow_move_constructible_v<T>
std::is_assignable_v<T>
std::is_trivially_assignable_v<T>
std::is_nothrow_assignable_v<T>
std::is_copy_assignable_v<T>
std::is_trivially_copy_assignable_v<T>
std::is_nothrow_copy_assignable_v<T>
std::is_move_assignable_v<T>
std::is_trivially_move_assignable_v<T>
std::is_nothrow_move_assignable_v<T>
RAII
inheritance
virtual
misc