C++ c++;复制控制问题

C++ c++;复制控制问题,c++,string,pointers,c++11,C++,String,Pointers,C++11,我认为输出应该是: #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

我认为输出应该是:

#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;
}
h: hi mom
h2: hi dad
h3: hi dad
我认为输出应该如上所述的原因:

#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;
}
h: hi mom
h2: hi dad
h3: hi dad
h是“hi mom”,h2共享h1,因此h2是“hi mom”,h3是“hi dad”,我认为
h2=h3
也改变了h1,因为h2共享h1,但事实并非如此

我做错了什么?

下面是发生的事情:

h: hi dad
h2: hi dad
h3: hi dad
指针是指向同一地址的不同实例。例如:

HasPtr h3("hi dad");
h2 = h3;

h2.ps ----> "hi dad" <--- h3.ps
 |
XXX changed
 |
"hi mom" <--- h.ps

更改<代码> P1 < /代码>(即<代码> p1=和c>代码>不会影响<代码> p2 >

,更清楚的是,让我们考虑一个简化的例子

int a = 5, c = 1; 
int *p1 = &a, *p2 = &a;
现在
h
h2
指向
x
。您可以在输出指针指向的对象时检查此项。比如说

int x = 10;
int y = 20;

int *h = &x;
int *h2 = h;
现在
h2
h3
指向
y
<代码>h未更改。你也可以检查这个

int *h3 = &y;
h2 = h3;
类的对象中只包装相应的指针(p)

下面是一个演示说明的程序

HasPtr h("hi mom");
HasPtr h2 = h;
HasPtr h3("hi dad");
h2 = h3;

我做错了什么?
:使用指针。如果使用对象,所有这些都会消失。另外,已经有一个参考计数智能指针
std::shared_ptr
h2=h3
根本不影响
h1
。您没有修改指向的内容,而是修改存储在
h2
中的指针。比较:为便于将来参考,您可能需要阅读有关和的信息。正如@LokiAstari所述,您可能也只想使用内置的
std::shared_ptr
。h2共享h1,直到您分配给h2为止。这是典型的引用计数-语义就像处理简单的值对象一样,但是拷贝会推迟到真正需要时。这是一个好主意,但实际上并不是一个胜利,特别是当你使用多线程时。还是不明白。h2的指针与h1的指针相同。如果h2改变,为什么h1不改变?@XIAODI指针是指向同一地址的不同实例。例如:
inta=5;int*p1=&a,*p2=&a
。更改
p1
(即
p1=&c
)不会影响
p2
谢谢,你能给我一个对应指针的例子吗?@XIAOD“对应指针”是像string*ps一样声明的数据成员ps;对应的对象h、h2和h3。事实上,该类只是围绕该指针的包装器,在我的示例中,我删除了包装器,只留下指针本身,并以与对象名称相同的方式命名它们。。
HasPtr h("hi mom");
HasPtr h2 = h;
HasPtr h3("hi dad");
h2 = h3;
#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;
}        
*h = hi mom, *h2 = hi mom
*h2 = hi dad, *h3 = hi dad
*h = hi mom