There are many pitfalls in move constructors. Please read the textbook before utilizing it.
BTW, this is just demonstration purpose for the pointer member to contain only one int value. In this particular case, replacing int *p with int v improves the performance much more,
C++ Program
#include <iostream>
#include <vector>
#include <stdio.h>
#include <map>
using namespace std;
static int PtrToId(const void* p) {
static int id = 400;
static map<const void*, int> ptrIdMap;
auto found = ptrIdMap.find(p);
if (found != ptrIdMap.end()) {
return found->second;
}
ptrIdMap[p] = id;
id += 8;
return ptrIdMap[p];
}
class A {
public:
int *p = nullptr;
static int newCounter;
A(void) {
p = new int;
++newCounter;
*p = 0;
cout << "Ctor new this=" << PtrToId(this) << ", p=" << PtrToId(p) << endl;
}
A(int d) {
p = new int;
++newCounter;
*p = d;
cout << "Ctor(int) this=" << PtrToId(this) << ", p=" << PtrToId(p) << ", *p=" << *p << endl;
}
A(const A& rhs) {
p = new int;
++newCounter;
*p = *(rhs.p);
cout << "Copy ctor this=" << PtrToId(this) << ", p=" << PtrToId(p) << ", *p=" << *p << endl;
}
~A(void) {
cout << "Dtor del this=" << PtrToId(this) << ", p=" << PtrToId(p) << ", *p=" << *p << endl;
delete p;
p = nullptr;
}
};
int A::newCounter = 0;
class B {
public:
int *p = nullptr;
static int newCounter;
B(void) {
p = new int;
++newCounter;
*p = 0;
cout << "Ctor new this=" << PtrToId(this) << ", p=" << PtrToId(p) << endl;
}
B(int d) {
p = new int;
++newCounter;
*p = d;
cout << "Ctor(int) this=" << PtrToId(this) << ", p=" << PtrToId(p) << ", *p=" << *p << endl;
};
B(const B& rhs) {
p = new int;
++newCounter;
*p = *(rhs.p);
cout << "Copy ctor this=" << PtrToId(this) << ", p=" << PtrToId(p) << ", *p=" << *p << ", &rhs=" << PtrToId(&rhs) << endl;
}
B(B&& rhs) noexcept {
p = rhs.p;
rhs.p = nullptr;
cout << "Move ctor this=" << PtrToId(this) << ", p=" << PtrToId(p) << ", *p=" << *p << ", &rhs=" << PtrToId(&rhs) << endl;
}
~B(void) {
if (p) {
cout << "Dtor del this=" << PtrToId(this) << ", p=" << PtrToId(p) << ", *p=" << *p << endl;
delete p;
p = nullptr;
} else {
cout << "Dtor this=" << PtrToId(this) << ", p=nullptr" << endl;
}
}
};
int B::newCounter = 0;
template <typename T>
static void Print(vector<T> &v, const char* name)
{
for (int i = 0; i < v.size(); ++i) {
printf(" &(%s[%d])=%d, p=%d, *p=%d\n", name, i, PtrToId(&(v[i])), PtrToId(v[i].p), *(v[i].p));
}
}
int main(void)
{
{
printf("vA/push_back Begin\n");
vector<A> vA;
printf("push_back(10)\n");
vA.push_back(10);
Print(vA, "vA");
printf("\npush_back(20)\n");
vA.push_back(20);
Print(vA, "vA");
printf("\npush_back(30)\n");
vA.push_back(30);
Print(vA, "vA");
printf("\nvA/push_back end\n");
}
printf("new int is called %d times.\n", A::newCounter);
A::newCounter = 0;
{
printf("\nvA/emplace_back Begin\n");
vector<A> vA;
printf("emplace_back(10)\n");
vA.emplace_back(10);
Print(vA, "vA");
printf("\nemplace_back(20)\n");
vA.emplace_back(20);
Print(vA, "vA");
printf("\nemplace_back(30)\n");
vA.emplace_back(30);
Print(vA, "vA");
printf("\nvA/emplace_back end\n");
}
printf("new int is called %d times.\n", A::newCounter);
{
printf("\nvB/push_back begin\n");
vector<B> vB;
printf("push_back(10)\n");
vB.push_back(10);
Print(vB, "vB");
printf("\npush_back(20)\n");
vB.push_back(20);
Print(vB, "vB");
printf("\npush_back(30)\n");
vB.push_back(30);
Print(vB, "vB");
printf("\nvB/push_back end\n");
}
printf("new int is called %d times.\n", B::newCounter);
B::newCounter = 0;
{
printf("\nvB/emplace_back begin\n");
vector<B> vB;
printf("emplace_back(10)\n");
vB.emplace_back(10);
Print(vB, "vB");
printf("\emplace_back(20)\n");
vB.emplace_back(20);
Print(vB, "vB");
printf("\emplace_back(30)\n");
vB.emplace_back(30);
Print(vB, "vB");
printf("\nvB/emplace_back end\n");
}
printf("new int is called %d times.\n", B::newCounter);
return 0;
}
#include <vector>
#include <stdio.h>
#include <map>
using namespace std;
static int PtrToId(const void* p) {
static int id = 400;
static map<const void*, int> ptrIdMap;
auto found = ptrIdMap.find(p);
if (found != ptrIdMap.end()) {
return found->second;
}
ptrIdMap[p] = id;
id += 8;
return ptrIdMap[p];
}
class A {
public:
int *p = nullptr;
static int newCounter;
A(void) {
p = new int;
++newCounter;
*p = 0;
cout << "Ctor new this=" << PtrToId(this) << ", p=" << PtrToId(p) << endl;
}
A(int d) {
p = new int;
++newCounter;
*p = d;
cout << "Ctor(int) this=" << PtrToId(this) << ", p=" << PtrToId(p) << ", *p=" << *p << endl;
}
A(const A& rhs) {
p = new int;
++newCounter;
*p = *(rhs.p);
cout << "Copy ctor this=" << PtrToId(this) << ", p=" << PtrToId(p) << ", *p=" << *p << endl;
}
~A(void) {
cout << "Dtor del this=" << PtrToId(this) << ", p=" << PtrToId(p) << ", *p=" << *p << endl;
delete p;
p = nullptr;
}
};
int A::newCounter = 0;
class B {
public:
int *p = nullptr;
static int newCounter;
B(void) {
p = new int;
++newCounter;
*p = 0;
cout << "Ctor new this=" << PtrToId(this) << ", p=" << PtrToId(p) << endl;
}
B(int d) {
p = new int;
++newCounter;
*p = d;
cout << "Ctor(int) this=" << PtrToId(this) << ", p=" << PtrToId(p) << ", *p=" << *p << endl;
};
B(const B& rhs) {
p = new int;
++newCounter;
*p = *(rhs.p);
cout << "Copy ctor this=" << PtrToId(this) << ", p=" << PtrToId(p) << ", *p=" << *p << ", &rhs=" << PtrToId(&rhs) << endl;
}
B(B&& rhs) noexcept {
p = rhs.p;
rhs.p = nullptr;
cout << "Move ctor this=" << PtrToId(this) << ", p=" << PtrToId(p) << ", *p=" << *p << ", &rhs=" << PtrToId(&rhs) << endl;
}
~B(void) {
if (p) {
cout << "Dtor del this=" << PtrToId(this) << ", p=" << PtrToId(p) << ", *p=" << *p << endl;
delete p;
p = nullptr;
} else {
cout << "Dtor this=" << PtrToId(this) << ", p=nullptr" << endl;
}
}
};
int B::newCounter = 0;
template <typename T>
static void Print(vector<T> &v, const char* name)
{
for (int i = 0; i < v.size(); ++i) {
printf(" &(%s[%d])=%d, p=%d, *p=%d\n", name, i, PtrToId(&(v[i])), PtrToId(v[i].p), *(v[i].p));
}
}
int main(void)
{
{
printf("vA/push_back Begin\n");
vector<A> vA;
printf("push_back(10)\n");
vA.push_back(10);
Print(vA, "vA");
printf("\npush_back(20)\n");
vA.push_back(20);
Print(vA, "vA");
printf("\npush_back(30)\n");
vA.push_back(30);
Print(vA, "vA");
printf("\nvA/push_back end\n");
}
printf("new int is called %d times.\n", A::newCounter);
A::newCounter = 0;
{
printf("\nvA/emplace_back Begin\n");
vector<A> vA;
printf("emplace_back(10)\n");
vA.emplace_back(10);
Print(vA, "vA");
printf("\nemplace_back(20)\n");
vA.emplace_back(20);
Print(vA, "vA");
printf("\nemplace_back(30)\n");
vA.emplace_back(30);
Print(vA, "vA");
printf("\nvA/emplace_back end\n");
}
printf("new int is called %d times.\n", A::newCounter);
{
printf("\nvB/push_back begin\n");
vector<B> vB;
printf("push_back(10)\n");
vB.push_back(10);
Print(vB, "vB");
printf("\npush_back(20)\n");
vB.push_back(20);
Print(vB, "vB");
printf("\npush_back(30)\n");
vB.push_back(30);
Print(vB, "vB");
printf("\nvB/push_back end\n");
}
printf("new int is called %d times.\n", B::newCounter);
B::newCounter = 0;
{
printf("\nvB/emplace_back begin\n");
vector<B> vB;
printf("emplace_back(10)\n");
vB.emplace_back(10);
Print(vB, "vB");
printf("\emplace_back(20)\n");
vB.emplace_back(20);
Print(vB, "vB");
printf("\emplace_back(30)\n");
vB.emplace_back(30);
Print(vB, "vB");
printf("\nvB/emplace_back end\n");
}
printf("new int is called %d times.\n", B::newCounter);
return 0;
}
Program Output
vA/push_back Begin
push_back(10)
Ctor(int) this=408, p=400, *p=10
Copy ctor this=424, p=416, *p=10
Dtor del this=408, p=400, *p=10
&(vA[0])=424, p=416, *p=10
push_back(20)
Ctor(int) this=440, p=432, *p=20
Copy ctor this=456, p=448, *p=20
Copy ctor this=472, p=464, *p=10
Dtor del this=424, p=416, *p=10
Dtor del this=440, p=432, *p=20
&(vA[0])=472, p=464, *p=10
&(vA[1])=456, p=448, *p=20
push_back(30)
Ctor(int) this=488, p=480, *p=30
Copy ctor this=496, p=416, *p=30
Copy ctor this=512, p=504, *p=10
Copy ctor this=528, p=520, *p=20
Dtor del this=472, p=464, *p=10
Dtor del this=456, p=448, *p=20
Dtor del this=488, p=480, *p=30
&(vA[0])=512, p=504, *p=10
&(vA[1])=528, p=520, *p=20
&(vA[2])=496, p=416, *p=30
vA/push_back end
Dtor del this=512, p=504, *p=10
Dtor del this=528, p=520, *p=20
Dtor del this=496, p=416, *p=30
new int is called 9 times.
vA/emplace_back Begin
emplace_back(10)
Ctor(int) this=472, p=480, *p=10
&(vA[0])=472, p=480, *p=10
emplace_back(20)
Ctor(int) this=544, p=536, *p=20
Copy ctor this=560, p=552, *p=10
Dtor del this=472, p=480, *p=10
&(vA[0])=560, p=552, *p=10
&(vA[1])=544, p=536, *p=20
emplace_back(30)
Ctor(int) this=576, p=568, *p=30
Copy ctor this=592, p=584, *p=10
Copy ctor this=608, p=600, *p=20
Dtor del this=560, p=552, *p=10
Dtor del this=544, p=536, *p=20
&(vA[0])=592, p=584, *p=10
&(vA[1])=608, p=600, *p=20
&(vA[2])=576, p=568, *p=30
vA/emplace_back end
Dtor del this=592, p=584, *p=10
Dtor del this=608, p=600, *p=20
Dtor del this=576, p=568, *p=30
new int is called 6 times.
vB/push_back begin
push_back(10)
Ctor(int) this=624, p=616, *p=10
Move ctor this=632, p=616, *p=10, &rhs=624
Dtor this=624, p=nullptr
&(vB[0])=632, p=616, *p=10
push_back(20)
Ctor(int) this=648, p=640, *p=20
Move ctor this=656, p=640, *p=20, &rhs=648
Move ctor this=664, p=616, *p=10, &rhs=632
Dtor this=632, p=nullptr
Dtor this=648, p=nullptr
&(vB[0])=664, p=616, *p=10
&(vB[1])=656, p=640, *p=20
push_back(30)
Ctor(int) this=680, p=672, *p=30
Move ctor this=688, p=672, *p=30, &rhs=680
Move ctor this=696, p=616, *p=10, &rhs=664
Move ctor this=704, p=640, *p=20, &rhs=656
Dtor this=664, p=nullptr
Dtor this=656, p=nullptr
Dtor this=680, p=nullptr
&(vB[0])=696, p=616, *p=10
&(vB[1])=704, p=640, *p=20
&(vB[2])=688, p=672, *p=30
vB/push_back end
Dtor del this=696, p=616, *p=10
Dtor del this=704, p=640, *p=20
Dtor del this=688, p=672, *p=30
new int is called 3 times.
vB/emplace_back begin
emplace_back(10)
Ctor(int) this=712, p=552, *p=10
&(vB[0])=712, p=552, *p=10
emplace_back(20)
Ctor(int) this=728, p=720, *p=20
Move ctor this=632, p=552, *p=10, &rhs=712
Dtor this=712, p=nullptr
&(vB[0])=632, p=552, *p=10
&(vB[1])=728, p=720, *p=20
emplace_back(30)
Ctor(int) this=576, p=448, *p=30
Move ctor this=592, p=552, *p=10, &rhs=632
Move ctor this=608, p=720, *p=20, &rhs=728
Dtor this=632, p=nullptr
Dtor this=728, p=nullptr
&(vB[0])=592, p=552, *p=10
&(vB[1])=608, p=720, *p=20
&(vB[2])=576, p=448, *p=30
vB/emplace_back end
Dtor del this=592, p=552, *p=10
Dtor del this=608, p=720, *p=20
Dtor del this=576, p=448, *p=30
new int is called 3 times.
push_back(10)
Ctor(int) this=408, p=400, *p=10
Copy ctor this=424, p=416, *p=10
Dtor del this=408, p=400, *p=10
&(vA[0])=424, p=416, *p=10
push_back(20)
Ctor(int) this=440, p=432, *p=20
Copy ctor this=456, p=448, *p=20
Copy ctor this=472, p=464, *p=10
Dtor del this=424, p=416, *p=10
Dtor del this=440, p=432, *p=20
&(vA[0])=472, p=464, *p=10
&(vA[1])=456, p=448, *p=20
push_back(30)
Ctor(int) this=488, p=480, *p=30
Copy ctor this=496, p=416, *p=30
Copy ctor this=512, p=504, *p=10
Copy ctor this=528, p=520, *p=20
Dtor del this=472, p=464, *p=10
Dtor del this=456, p=448, *p=20
Dtor del this=488, p=480, *p=30
&(vA[0])=512, p=504, *p=10
&(vA[1])=528, p=520, *p=20
&(vA[2])=496, p=416, *p=30
vA/push_back end
Dtor del this=512, p=504, *p=10
Dtor del this=528, p=520, *p=20
Dtor del this=496, p=416, *p=30
new int is called 9 times.
vA/emplace_back Begin
emplace_back(10)
Ctor(int) this=472, p=480, *p=10
&(vA[0])=472, p=480, *p=10
emplace_back(20)
Ctor(int) this=544, p=536, *p=20
Copy ctor this=560, p=552, *p=10
Dtor del this=472, p=480, *p=10
&(vA[0])=560, p=552, *p=10
&(vA[1])=544, p=536, *p=20
emplace_back(30)
Ctor(int) this=576, p=568, *p=30
Copy ctor this=592, p=584, *p=10
Copy ctor this=608, p=600, *p=20
Dtor del this=560, p=552, *p=10
Dtor del this=544, p=536, *p=20
&(vA[0])=592, p=584, *p=10
&(vA[1])=608, p=600, *p=20
&(vA[2])=576, p=568, *p=30
vA/emplace_back end
Dtor del this=592, p=584, *p=10
Dtor del this=608, p=600, *p=20
Dtor del this=576, p=568, *p=30
new int is called 6 times.
vB/push_back begin
push_back(10)
Ctor(int) this=624, p=616, *p=10
Move ctor this=632, p=616, *p=10, &rhs=624
Dtor this=624, p=nullptr
&(vB[0])=632, p=616, *p=10
push_back(20)
Ctor(int) this=648, p=640, *p=20
Move ctor this=656, p=640, *p=20, &rhs=648
Move ctor this=664, p=616, *p=10, &rhs=632
Dtor this=632, p=nullptr
Dtor this=648, p=nullptr
&(vB[0])=664, p=616, *p=10
&(vB[1])=656, p=640, *p=20
push_back(30)
Ctor(int) this=680, p=672, *p=30
Move ctor this=688, p=672, *p=30, &rhs=680
Move ctor this=696, p=616, *p=10, &rhs=664
Move ctor this=704, p=640, *p=20, &rhs=656
Dtor this=664, p=nullptr
Dtor this=656, p=nullptr
Dtor this=680, p=nullptr
&(vB[0])=696, p=616, *p=10
&(vB[1])=704, p=640, *p=20
&(vB[2])=688, p=672, *p=30
vB/push_back end
Dtor del this=696, p=616, *p=10
Dtor del this=704, p=640, *p=20
Dtor del this=688, p=672, *p=30
new int is called 3 times.
vB/emplace_back begin
emplace_back(10)
Ctor(int) this=712, p=552, *p=10
&(vB[0])=712, p=552, *p=10
emplace_back(20)
Ctor(int) this=728, p=720, *p=20
Move ctor this=632, p=552, *p=10, &rhs=712
Dtor this=712, p=nullptr
&(vB[0])=632, p=552, *p=10
&(vB[1])=728, p=720, *p=20
emplace_back(30)
Ctor(int) this=576, p=448, *p=30
Move ctor this=592, p=552, *p=10, &rhs=632
Move ctor this=608, p=720, *p=20, &rhs=728
Dtor this=632, p=nullptr
Dtor this=728, p=nullptr
&(vB[0])=592, p=552, *p=10
&(vB[1])=608, p=720, *p=20
&(vB[2])=576, p=448, *p=30
vB/emplace_back end
Dtor del this=592, p=552, *p=10
Dtor del this=608, p=720, *p=20
Dtor del this=576, p=448, *p=30
new int is called 3 times.
No comments:
Post a Comment