为什么我可以在C ++中将常量shared_ptr分配给非常量shared_ptr?

kad*_*ina 2 c++ const

我以为我不能将一个常量分配shared_ptr给一个非常量shared_ptr。但令人惊讶的是,我能够按以下方式进行分配,并且工作正常。

#include <iostream>
#include <memory>

using namespace std;

int main()
{
    const std::shared_ptr<const string> a = std::make_shared<const string>("Hello world");

    std::shared_ptr<const string> b = a;
    cout << "a count " << a.use_count() << ", b count " << b.use_count() << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

.use_count() 显示为2。请问有人可以帮助我了解我的能力吗?

Yks*_*nen 10

您的代码中的情况与此处完全相同:

const int a = 5;
int b = a;
std::cout << "a=" << a ", b=" << b << std::endl; // a=5, b=5
b = 10;
std::cout << "a=" << a ", b=" << b << std::endl; //a=5, b=10
Run Code Online (Sandbox Code Playgroud)

并不奇怪,对吧?我有const int,我用它来初始化non-const int。来自的值a被复制到,b并且a根本没有被修改。

也会发生相同的情况const std::shared_ptr。复制构造另一个对象不会修改原始对象。

use_count可以更改,因为它不是std::shared_ptr课程的成员。std::shared_ptr需要在堆上分配两个内存块-一个控制块和实际对象块。
每个std::shared_ptr实例仅存储指向控制块和实际对象的指针。控制块存储使用计数(std::shared_ptr持有指向它的指针的s的数量)。

复制时std::shared_ptr,它会增加控制块中的使用次数,并获得相同的两个指针。当std::shared_ptr模具,它递减的使用计数(并且如果使用计数达到0删除两个块)。

因此,总结一下:use count不是的成员std::shared_ptr,因此它甚至可以更改const std::shared_ptr(否则const std::shared_ptr将毫无用处)。

  • @kadina因为`const char *`和`const shared_ptr &lt;T&gt;`不一样。在`const char *`中,`const`适用于`char`,而不是`*`。同样,您需要`char * const`,并且可以将**分配给`char * `。 (3认同)
  • @kadina,因为类似于const char *的是std :: shared_ptr &lt;const char&gt;而不是const std :: shared_ptr &lt;char&gt; (2认同)

Ted*_*gmo 7

stringab指向的仍然是const在这两种情况下,但指针b是不是,所以你可以改变什么b是在指点:

std::shared_ptr<const string> b = a;
b = std::make_shared<const string>("New string");
Run Code Online (Sandbox Code Playgroud)

但是你不能改变什么a在(因为指向aconst):

a = std::make_shared<const string>("Won't compile");
Run Code Online (Sandbox Code Playgroud)

类似地:

const char* const a = "Hello world";
const char* b = a;

const char* c = "Something else";
b = c;    // the pointer "b" is not const and can be changed
// a = c; // won't compile since the pointer "a" itself is const
Run Code Online (Sandbox Code Playgroud)