shared_ptr和const [英] shared_ptr and const

查看:122
本文介绍了shared_ptr和const的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我理解为什么它按照它的方式工作的语义。但是我想知道是否有理由在行标记为

QUESTION。我想如果有答案,有人在这里知道。


具体来说,第1部分对大多数人来说都是显而易见的。第2部分与第1部分同构

,但表现不同。如果shared_ptr是const,那么

它真的允许非常量的dereferences吗?


谢谢,


Tim


#include< boost / shared_ptr.hpp>


int main(无效)

{

//第1部分

int * pi = new int(1);

const int * cpi = new int(2);


* pi = 11; // ok

* cpi = 22; //编译错误


//第2部分

boost :: shared_ptr< intspi(new int(3));

const boost :: shared_ptr< intcspi(new int(4));


* spi = 33; // ok

* cspi = 44; //问题:这应该是编译

错误吗?


//第3部分

boost :: shared_ptr< const intspci (new int(5));

const boost :: shared_ptr< const intcspci(new int(6));


* spci = 44; //编译错误

* cspci = 55; //编译错误


返回0;

}

解决方案

Tim H写道:


>

//第2部分

boost :: shared_ptr< intspi(new int(3));

const boost :: shared_ptr< intcspi(new int(4));


* spi = 33; // ok

* cspi = 44; //问题:这应该是编译

错误吗?



答案:不。 cspi是一个指向int的const指针,而不是指向const int的指针。

类似的指针是:


int * const cip;


-


- Pete

Roundhouse Consulting,Ltd。( www.versatilecoding.com

标准C ++库扩展:一个教程和
的作者
参考。 ( www.petebecker.com/tr1book


Tim H写道:


我理解为什么这样做的语义。但是我想知道是否有理由在行标记为

QUESTION。我想如果有答案,有人在这里知道。


具体来说,第1部分对大多数人来说都是显而易见的。第2部分与第1部分同构

,但表现不同。如果shared_ptr是const,那么

它真的允许非常量的dereferences吗?


谢谢,


Tim


#include< boost / shared_ptr.hpp>


int main(无效)

{

//第1部分

int * pi = new int(1);

const int * cpi = new int(2);


* pi = 11; // ok

* cpi = 22; //编译错误


//第2部分

boost :: shared_ptr< intspi(new int(3));

const boost :: shared_ptr< intcspi(new int(4));


* spi = 33; // ok

* cspi = 44; //问题:这应该是编译

错误吗?



如果有人回复你,你会混淆const int *实际上是

相当于int const *和shared_ptr< const intwith" int * const"

,相当于const shared_ptr< int> (或shared_ptr< int>

const)。


在第一种情况下,指向的内存是常量。在第二个

的情况下,指针本身(或shared_ptr)是恒定的。


通常更喜欢T const *的形式;结束于const T *因为:

1.它不会产生这样的混淆

2.在处理模板代码时它不会给你带来奇怪的错误和

typedef,此类代码的示例(引自C ++模板完整指南):


typedef char * CHARS;

typedef CHARS const CPTR; //指向字符的常量指针


当我们以文本替换

CHARS时,保留第二个声明的含义:

typedef char * const CPTR; //对字符的常量指针


但是,如果我们在它符合条件的类型之前编写const,这个原则

不适用。实际上,考虑前面提到的前两种类型

定义的替代方案:

typedef char * CHARS;

typedef const CHARS CPTR; //指向字符的常量指针


文本替换CHARS会产生具有不同含义的类型:

typedef const char * CPTR; //指向常量字符的指针


typedef在文本上被替换,因此在const类型之前使用const

时可能会出错。


//第3部分

boost :: shared_ptr< const intspci(new int(5));

const boost :: shared_ptr< const intcspci(new int(6));


* spci = 44; //编译错误

* cspci = 55; //编译错误


返回0;

}



shared_ptr<尝试表现得像正常的指针/引用。并且使用

指针/引用,您可以使用所谓的按位常量。选择

到逻辑constness,即有一个const指针(int * const pi =& i)

并不限制访问对于指向的内存,它只是限制了对指针本身的访问(pi =& another;将错误但是* pi = 10

不会)。


总之,如果你不希望非const访问指向的对象

那么就把它做成 shared_ptr< T const>"而不是shared_ptr< Tconst。他们是非常不同的...


-

Dizzy


5月29日上午6:11,Dizzy< d ... @ roedu.netwrote:


Tim H写道:


我理解为什么它按照它的方式工作的语义。但是我想知道是否有理由在行标记为

QUESTION。我想如果有答案,有人在这里知道。


具体来说,第1部分对大多数人来说都是显而易见的。第2部分与第1部分同构

,但表现不同。如果ashared_ptris const,应该

它真的允许非常量的dereferences吗?


谢谢,


Tim


#include< boost / shared_ptr.hpp>


int main(void)

{

//第1部分

int * pi = new int(1);

const int * cpi = new int(2);


* pi = 11; // ok

* cpi = 22; //编译错误


//第2部分

boost :: shared_ptr< intspi(new int(3));

const boost :: shared_ptr< intcspi(new int(4));


* spi = 33; // ok

* cspi = 44; //问题:这应该是编译

错误吗?



正如有人已经回答你混淆了const int *实际上是

相当于int const * andshared_ptr< const intwith" int * const"

,相当于constshared_ptr< int> (或shared_ptr< int>

const)。


总之,如果你不希望非const访问指向的对象

那么就把它做成" shared_ptr< T const>"而不是shared_ptr< Tconst。他们是非常不同的...



我完全了解字面差异。我很好奇的是

本地指针的并行性。


为什么会这样?为什么sub_ class shared_ptr和

make" operator->()const"和operator *()const返回const

引用?


并行使用是我想要的。


const int * cpi = new int;

const shared_ptr< intshcpi = new int;


* cpi = 2;

* thcpi = 2;


这个例子很容易改变,但我看到的每一段代码都是


typedef shared_ptr< intint_ptr;


所以现在我们总是要为const_int_ptr设置第二个typedef;


打造一个简单的子类很容易。那么为什么这是一个坏主意呢?


谢谢,


Tim

I understand the semantics of why this works the way it does. But I
wonder if there''s a reason for the behaviore at the line marked
"QUESTION". I figured if there is an answer, someone here knows it.

Specifically, part 1 is obvious to most anyone. Part 2 is isomorphic
to part 1, yet behaves differently. If a shared_ptr is const, should
it really allow non-const dereferences?

Thanks,

Tim

#include <boost/shared_ptr.hpp>

int main(void)
{
// part 1
int *pi = new int(1);
const int *cpi = new int(2);

*pi = 11; // ok
*cpi = 22; // compile error

// part 2
boost::shared_ptr<intspi(new int(3));
const boost::shared_ptr<intcspi(new int(4));

*spi = 33; // ok
*cspi = 44; // QUESTION: should this be a compile
error?

// part 3
boost::shared_ptr<const intspci(new int(5));
const boost::shared_ptr<const intcspci(new int(6));

*spci = 44; // compile error
*cspci = 55; // compile error

return 0;
}

解决方案

Tim H wrote:

>
// part 2
boost::shared_ptr<intspi(new int(3));
const boost::shared_ptr<intcspi(new int(4));

*spi = 33; // ok
*cspi = 44; // QUESTION: should this be a compile
error?

ANSWER: no. cspi is a const pointer to int, not a pointer to const int.
The analogous pointer would be:

int * const cip;

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)


Tim H wrote:

I understand the semantics of why this works the way it does. But I
wonder if there''s a reason for the behaviore at the line marked
"QUESTION". I figured if there is an answer, someone here knows it.

Specifically, part 1 is obvious to most anyone. Part 2 is isomorphic
to part 1, yet behaves differently. If a shared_ptr is const, should
it really allow non-const dereferences?

Thanks,

Tim

#include <boost/shared_ptr.hpp>

int main(void)
{
// part 1
int *pi = new int(1);
const int *cpi = new int(2);

*pi = 11; // ok
*cpi = 22; // compile error

// part 2
boost::shared_ptr<intspi(new int(3));
const boost::shared_ptr<intcspi(new int(4));

*spi = 33; // ok
*cspi = 44; // QUESTION: should this be a compile
error?

As someone already replied you confuse "const int*" which is actually
equivalent to "int const*" and shared_ptr<const intwith "int* const"
which is equivalent to "const shared_ptr<int>" (or "shared_ptr<int>
const").

In the first case it''s the memory pointed to that is constant. In the second
case it''s the pointer itself (or shared_ptr) that is constant.

Generally prefer the form of "T const*" over to "const T*" because:
1. it doesn''t create such confusions
2. it will not give you strange errors when dealing with template code and
typedefs, example of such code(quote from C++ Templates Complete Guide):

typedef char* CHARS;
typedef CHARS const CPTR; // constant pointer to chars

The meaning of the second declaration is preserved when we textually replace
CHARS with what it stands for:
typedef char* const CPTR; // constant pointer to chars

However, if we write const before the type it qualifies, this principle
doesn''t apply. Indeed, consider the alternative to our first two type
definitions presented earlier:
typedef char* CHARS;
typedef const CHARS CPTR; // constant pointer to chars

Textually replacing CHARS results in a type with a different meaning:
typedef const char* CPTR; // pointer to constant chars

typedefs are textually replaced thus can get into errors when using const
before the const type.

// part 3
boost::shared_ptr<const intspci(new int(5));
const boost::shared_ptr<const intcspci(new int(6));

*spci = 44; // compile error
*cspci = 55; // compile error

return 0;
}

shared_ptr<tries to behave like a normal pointer/reference. And with
pointer/references you have what is called "bitwise constness" as oposed
to "logical constness", ie having a const pointer ("int* const pi = &i")
doesn''t restrict the access to the memory pointed to, it just restricts the
access to the pointer itself ("pi = &another;" will error but "*pi = 10"
will not).

In conclusion, if you don''t want non-const access to the pointed to object
then make it "shared_ptr<T const>" and not "shared_ptr<Tconst". They are
very different...

--
Dizzy


On May 29, 6:11 am, Dizzy <d...@roedu.netwrote:

Tim H wrote:

I understand the semantics of why this works the way it does. But I
wonder if there''s a reason for the behaviore at the line marked
"QUESTION". I figured if there is an answer, someone here knows it.

Specifically, part 1 is obvious to most anyone. Part 2 is isomorphic
to part 1, yet behaves differently. If ashared_ptris const, should
it really allow non-const dereferences?

Thanks,

Tim

#include <boost/shared_ptr.hpp>

int main(void)
{
// part 1
int *pi = new int(1);
const int *cpi = new int(2);

*pi = 11; // ok
*cpi = 22; // compile error

// part 2
boost::shared_ptr<intspi(new int(3));
const boost::shared_ptr<intcspi(new int(4));

*spi = 33; // ok
*cspi = 44; // QUESTION: should this be a compile
error?


As someone already replied you confuse "const int*" which is actually
equivalent to "int const*" andshared_ptr<const intwith "int* const"
which is equivalent to "constshared_ptr<int>" (or "shared_ptr<int>
const").

In conclusion, if you don''t want non-const access to the pointed to object
then make it "shared_ptr<T const>" and not "shared_ptr<Tconst". They are
very different...


I fully apprciate the literal difference. What I am curious about is
parallelism to native pointers.

WHY is it so? Why would it be a bad idea to sub-class shared_ptr and
make "operator->() const" and "operator*() const" return const
references?

The parallel usage is what I want.

const int *cpi = new int;
const shared_ptr<intshcpi = new int;

*cpi = 2;
*thcpi = 2;

This example is trivial to change, but every piece of code I see does

typedef shared_ptr<intint_ptr;

So now we always have to have a second typedef for const_int_ptr;

Whipping up a trivial sub-class is easy. So why is it a bad idea?

Thanks,

Tim


这篇关于shared_ptr和const的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆