简体   繁体   English

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

[英]Why I am able to assign constant shared_ptr to non constant shared_ptr in C++?

I thought I can't assign a constant shared_ptr to a non-constant shared_ptr . 我以为我不能将常量shared_ptr分配给非常量shared_ptr But surprisingly I am able to assign as below and it is working fine. 但令人惊讶的是,我能够分配如下,它工作正常。

#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;
}

.use_count() is getting printed as 2. Can any one please help me to understand how I am able to do it? .use_count()打印为2.任何人都可以帮助我理解我是如何做到的吗?

The situation in your code is exactly the same as here: 代码中的情况与此处完全相同:

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

Not particularly surprising, right? 不是特别令人惊讶,对吧? I had const int , and I used it to initialize non-const int . 我有const int ,我用它来初始化非const int The value from a got copied into b and a wasn't modified at all. 从价值a得到复制到ba没有被修改的。

Same occurs with const std::shared_ptr . const std::shared_ptr Copy-constructing another object is not modifying the original object. 复制构造另一个对象不会修改原始对象。

use_count can be changed, because it's not a member of std::shared_ptr class. use_count可以更改,因为它不是std::shared_ptr类的成员。 std::shared_ptr requires two memory blocks allocated on the heap - a control block and actual object block. std::shared_ptr需要在堆上分配两个内存块 - 一个控制块和一个实际的对象块。
Every std::shared_ptr instance only stores a pointer to the control block and to the actual object. 每个std::shared_ptr实例只存储一个指向控制块和实际对象的指针。 The control block stores use count (number of std::shared_ptr s that hold the pointer to it). 控制块存储使用计数(保存指向它的指针的std::shared_ptr的数量)。

When you copy std::shared_ptr , it increments the use count in control block and gets the same two pointers. 复制std::shared_ptr ,它会增加控制块中的使用计数并获得相同的两个指针。 When std::shared_ptr dies, it decrements use count (and deletes both blocks if use count reaches 0). std::shared_ptr死亡时,它会减少使用计数(如果使用计数达到0,则删除两个块)。

So, to sum up: use count is not a member of std::shared_ptr , and as such it can change even for const std::shared_ptr (otherwise const std::shared_ptr would be quite useless). 因此,总结一下:use count不是std::shared_ptr的成员,因此它甚至可以改变const std::shared_ptr (否则const std::shared_ptr将毫无用处)。

The string that a and b are pointing at is still const in both cases, but the pointer b isn't, so you could change what b is pointing at: 在两种情况下, ab 指向string仍然是const ,但是指针b不是,所以你可以改变b指向的内容:

std::shared_ptr<const string> b = a;
b = std::make_shared<const string>("New string");

But you can't change what a is pointing at (since a is const ): 但你不能改变a正指向(因为aconst ):

a = std::make_shared<const string>("Won't compile");

Similarly: 同理:

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

Let's simplify: 让我们简化一下:

#include <iostream>
#include <memory>

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

    auto b = a;
    std::cout << "a count " << a.use_count() << ", b count " << b.use_count() << "\n";
}

Types allowing copy-construction from a mutable object, but not from a constant one, are very rare and all user-defined. 允许来自可变对象的复制构造的类型,但不是来自常量对象的类型,是非常罕见的并且都是用户定义的。 Mostly, they pre-date move-semantics, and thus C++11. 大多数情况下,它们都是早期的移动语义,因此也就是C ++ 11。
std::shared_ptr , introduced with C++11, is not such an exception. 与C ++ 11一起引入的std::shared_ptr并不是一个例外。 Why should it? 为什么要这样?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM