shared_ptr和const [英] shared_ptr and 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屋!