C ++ copy control problem
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class HasPtr{
public:
//constructor accepts a string
HasPtr(const string &s = string()) : ps(new string(s)), i(0), use(new size_t(1)) {}
//copy constructor
HasPtr(const HasPtr &h) : ps(h.ps), i(h.i), use(h.use) { ++*use; }
//copy assignment operator
HasPtr &operator=(const HasPtr &h)
{
++*h.use;
if(--*use == 0)
{
delete ps;
delete use;
}
ps = h.ps;
i = h.i;
use = h.use;
return *this;
}
~HasPtr()
{
if(--*use == 0)
{
delete ps;
delete use;
}
}
//private:
string *ps;
int i;
size_t *use;
};
int main()
{
HasPtr h("hi mom");
HasPtr h2 = h;
HasPtr h3("hi dad");
h2 = h3;
cout << "h: " << *h.ps << endl;
cout << "h2: " << *h2.ps << endl;
cout << "h3: " << *h3.ps << endl;
}
Output:
h: hi mom
h2: hi dad
h3: hi dad
I think the output should be:
h: hi dad
h2: hi dad
h3: hi dad
The reason why I think the output should look like above:
h is "hi mom", h2 is h1 share, so h2 is "hi mom", h3 is "hi dad" and I think I h2 = h3
changed h1 either because h2 is divisible by h1, but it is not.
What am I doing wrong?
source to share
To make it clearer, consider a simplified example
int x = 10;
int y = 20;
int *h = &x;
int *h2 = h;
Now h
they h2
point to x
. You can check this output of the object pointed to by pointers. for example
std::cout << "*h = " << *h << ", *h2 = " << *h2 << std::endl;
Then you use the third pointer
int *h3 = &y; h2 = h3;
Now h2
they h3
point to y
. h
has not been changed. You can also check this
std::cout << "*h2 = " << *h2 << ", *h3 = " << *h3 << std::endl;
std::cout << "*h = " << *h << std::endl;
The same happens with your objects in statements
HasPtr h("hi mom");
HasPtr h2 = h;
HasPtr h3("hi dad");
h2 = h3;
only the relevant pointers (ps) are wrapped in class objects.
Here is a program that demonstrates the explanation
#include <iostream>
#include <string>
int main()
{
std::string hi_mom( "hi mom" );
std::string hi_dad( "hi dad" );
std::string *h = &hi_mom;
std::string *h2 = h;
std::cout << "*h = " << *h << ", *h2 = " << *h2 << std::endl;
std::string *h3 = &hi_dad;
h2 = h3;
std::cout << "*h2 = " << *h2 << ", *h3 = " << *h3 << std::endl;
std::cout << "*h = " << *h << std::endl;
}
Its conclusion
*h = hi mom, *h2 = hi mom
*h2 = hi dad, *h3 = hi dad
*h = hi mom
source to share
Here's what's going on:
HasPtr h("hi mom");
HasPtr h2 = h;
h.ps ---> "hi mom" <--- h2.ps
Then with the following statement, you change h2
, but it doesn't affect h
:
HasPtr h3("hi dad");
h2 = h3;
h2.ps ----> "hi dad" <--- h3.ps
|
XXX changed
|
"hi mom" <--- h.ps
Pointers are different instances pointing to the same address. Example:
int a = 5, c = 1;
int *p1 = &a, *p2 = &a;
Change p1
(i.e. p1 = &c
) will not affect p2
.
source to share