指针数据成员的const正确性 [英] Const correctness for pointer data members

查看:79
本文介绍了指针数据成员的const正确性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,


我一直在使用这种代码:


class Foo

{

public:

void NonConstMethod()

{}

};

班级酒吧

{

公开:

// [...](简化课程)


void NonLogicallyConstMethod()const

{

m_pBar-> NonConstMethod();

}

私人:

Foo * const m_pBar;


};


虽然这被接受编译器,因此const-correct,

我经常发现自己是否真的感到困惑,并且

逻辑上是const-correct。

只是发生NonLogicallyConstMethod()可以调用const

方法,因为Bar与Foo关联的方式即如果我使用了

类成员变量,则不允许这样做。

指针本身是const的事实看起来像是一种解决方法(与使用

< mutable>不同)。


我错过了什么?

谢谢,

Quantdev2004

Hi all,

I have been deling with this kind of code:

class Foo
{
public:
void NonConstMethod()
{}
};

class Bar
{
public:
// [...] (Class simplified)

void NonLogicallyConstMethod() const
{
m_pBar->NonConstMethod();
}
private:
Foo* const m_pBar;

};

Although this is accepted by the compiler, and therefore const-correct,
I often find myself puzzled as to whether this is actually and
logically const-correct.
It just happens that NonLogicallyConstMethod() can invoke a const
method because of the way Bar is associated to Foo i.e. If I used a
class member variable this would not be allowed. The fact that the
pointer itself is const looks like a workaround (not unlike using
<mutable>).

What am I missing?
Thanks,
Quantdev2004

推荐答案

On 2005年10月4日07:13:50 -0700, qu ********** @ yahoo .co.uk 写道:
On 4 Oct 2005 07:13:50 -0700, qu**********@yahoo.co.uk wrote:
大家好,

我一直在使用这种代码:
Foo
{
公开:
void NonConstMethod()
{}
};

班级酒吧
{<公开:
// [...](类简化)

void NonLogicallyConstMethod()const
{
m_pBar-> NonConstMethod();
}
私人:
Foo * const m_pBar;

};

虽然这是编译器接受的,因此const-正确的,
我经常发现自己是否真的和逻辑上一致的错误。
它ju st发生NonLogicallyConstMethod()可以调用const
方法,因为Bar与Foo关联的方式,即如果我使用了一个
类成员变量,则不允许这样做。
指针本身是const的事实看起来像是一种解决方法(与使用
< mutable>不同)。

我缺少什么?
谢谢,
Quantdev2004
Hi all,

I have been deling with this kind of code:

class Foo
{
public:
void NonConstMethod()
{}
};

class Bar
{
public:
// [...] (Class simplified)

void NonLogicallyConstMethod() const
{
m_pBar->NonConstMethod();
}
private:
Foo* const m_pBar;

};

Although this is accepted by the compiler, and therefore const-correct,
I often find myself puzzled as to whether this is actually and
logically const-correct.
It just happens that NonLogicallyConstMethod() can invoke a const
method because of the way Bar is associated to Foo i.e. If I used a
class member variable this would not be allowed. The fact that the
pointer itself is const looks like a workaround (not unlike using
<mutable>).

What am I missing?
Thanks,
Quantdev2004




你缺少的是const-ness(或者用C ++标准说话,

" cv - 指针的资格化绝对没有任何关系

与它指向的东西的const-ness(或cv-qualification)

至。这是完全不同的两件事。


-

Bob Hairgrove
没有********** @ Home.com


qu ********** @ yahoo.co.uk 写道:
我一直在使用这种代码:

类Foo
{
公开:
void NonConstMethod()
{}
};

课程栏
{
公开:
// [...](简化课程)

void NonLogicallyConstMethod( )const
{
m_pBar-> NonConstMethod();
}
私人:
Foo * const m_pBar;


这是一个指向可变(非常数)Foo的常量指针。

};

虽然这是被接受的由编译器,因此const-correct,
我经常发现自己是否真的和逻辑上的const-correct一样困惑。


未知。 ''Bar''*拥有*他''Foo''的副本,''m_pBar''(顺便说一句,你知道这个名字可能会有点纠正,比如' 'm_pFoo''?)

指向?如果它拥有它,那么你可能是对的,逻辑是有点搞砸了。如果它不拥有它,它可能无关紧要。

只是碰巧NonLogicallyConstMethod()可以调用const
方法


Isn 实际上反之亦然:它可以调用NON-const方法吗?

因为Bar与Foo关联的方式,即如果我使用了一个
类成员变量,那么这不会是允许。


在这种情况下,''Foo''* object *本身就是const。


指针本身是const的事实看起来喜欢解决方法(不像使用
< mutable>)。

我缺少什么?
I have been deling with this kind of code:

class Foo
{
public:
void NonConstMethod()
{}
};

class Bar
{
public:
// [...] (Class simplified)

void NonLogicallyConstMethod() const
{
m_pBar->NonConstMethod();
}
private:
Foo* const m_pBar;
It''s a constant pointer to a mutable (non-constant) Foo.

};

Although this is accepted by the compiler, and therefore const-correct,
I often find myself puzzled as to whether this is actually and
logically const-correct.
Unknown. Does ''Bar'' *own* his copy of ''Foo'', to which ''m_pBar'' (BTW, do
you think that the name could be a bit corrected, like ''m_pFoo''?) is
pointing? If it does own it, then you''re probably right, the logic is
a bit screwed up. If it does not own it, it probably does not matter.
It just happens that NonLogicallyConstMethod() can invoke a const
method
Isn''t it actually vice versa: it can invoke a NON-const method?
because of the way Bar is associated to Foo i.e. If I used a
class member variable this would not be allowed.
In that case the ''Foo'' *object* itself would be const.
The fact that the
pointer itself is const looks like a workaround (not unlike using
<mutable>).

What am I missing?




一本好书,也许?并考虑在自己的课程中允许什么以及什么不允许
允许...


V



A good book, maybe? And thinking about what to allow and what not to
allow in your own classes...

V

quantdev2 ... @ yahoo.co.uk写道:
quantdev2...@yahoo.co.uk wrote:
大家好,

我一直在使用这种代码:
<课堂Foo
{
公开:
无效NonConstMethod()
{}
};

班级酒吧
{
公开:
// [...](类简化)

void NonLogicallyConstMethod()const
{
m_pBar-> NonConstMethod( );
}
私有:
Foo * const m_pBar;

};

虽然这是编译器接受的,因此const-correct,
我经常发现自己对这是否真的和逻辑上的const-correct感到困惑。
只是发生NonLogicallyConstMethod()可以调用const
方法,因为Bar与Foo关联的方式即如果我使用了一个
类成员变量,那就不是全部了拖欠。
指针本身是const的事实看起来像是一种解决方法(与使用
< mutable>不同)。

我缺少什么?
谢谢,
Quantdev2004
Hi all,

I have been deling with this kind of code:

class Foo
{
public:
void NonConstMethod()
{}
};

class Bar
{
public:
// [...] (Class simplified)

void NonLogicallyConstMethod() const
{
m_pBar->NonConstMethod();
}
private:
Foo* const m_pBar;

};

Although this is accepted by the compiler, and therefore const-correct,
I often find myself puzzled as to whether this is actually and
logically const-correct.
It just happens that NonLogicallyConstMethod() can invoke a const
method because of the way Bar is associated to Foo i.e. If I used a
class member variable this would not be allowed. The fact that the
pointer itself is const looks like a workaround (not unlike using
<mutable>).

What am I missing?
Thanks,
Quantdev2004




你没有遗漏任何东西。常数很浅。也就是说,C ++确实不会将指针从指针转移到指针。 (在你的情况下,

m_pBar总是const,但是如果你删除那个const,它会变成const方法中的
const,虽然指针不会)。 />

关于这个NG和其他人讨论过为什么这个

是否违反const-correctness。我发现行为

非直观,并且认为constness应该转移到指针对象

在这些情况下并在必要时被覆盖,类似于可变的

声明,但更改语言会破坏现有代码的大量优惠。


要获得所需的行为,您可以执行以下操作:


模板< class T>

类DeepPtr

{

public:

DeepPtr(T * const ptr):m_ptr(ptr){assert(m_ptr); }

DeepPtr(DeepPtr< T>& ptr):m_ptr(ptr.m_ptr){}


//标准访问

T * operator->(){return m_ptr; }

T& operator *(){return * m_ptr; }

T& operator [](ui32 n){return m_ptr [n]; } $ / $

//如果指针是const,则使指针const成为

T const * operator->()const {return m_ptr; }

T const& operator *()const {return * m_ptr; }

T const& operator [](ui32 n)const {return m_ptr [n]; }


私人:

T * const m_ptr;


//已禁用方法

DeepPtr(const DeepPtr&);

DeepPtr& operator =(const DeepPtr&);

};


struct Foo

{

void NonConst(){};

};


struct bar

{

Bar(Foo) * pFoo):m_pFoo(pFoo){}

void Const()const {m_pFoo-> NonConst(); } //错误!

私人:

DeepPtr< Foo> m_pFoo;

};


不幸的是,禁用的复制构造函数和赋值运算符

意味着这样的指针不能用于一个标准的容器。


干杯! --M



You''re not missing anything. Constness is shallow. That is, C++ does
not transfer constness from the pointer to the pointee. (In your case,
m_pBar is always const, but if you removed that const, it would become
const in const methods, though the pointee would not).

There have been many discussions on this NG and others about why this
is or is not a violation of const-correctness. I find the behavior
non-intuitive and think constness should be transferred to the pointee
in these cases and overridden when necessary with mutable-like
declaration, but changing the language would break a good deal of
existing code.

To get the behavior you want, you can do something like this:

template <class T>
class DeepPtr
{
public:
DeepPtr( T *const ptr ) : m_ptr( ptr ) { assert(m_ptr); }
DeepPtr( DeepPtr<T>& ptr ) : m_ptr( ptr.m_ptr ) {}

// Standard access
T* operator->() { return m_ptr; }
T& operator*() { return *m_ptr; }
T& operator[]( ui32 n ) { return m_ptr[ n ]; }

// Make pointee const if pointer is const
T const* operator->() const { return m_ptr; }
T const& operator*() const { return *m_ptr; }
T const& operator[]( ui32 n ) const { return m_ptr[ n ]; }

private:
T * const m_ptr;

// Disabled methods
DeepPtr( const DeepPtr& );
DeepPtr& operator=( const DeepPtr& );
};

struct Foo
{
void NonConst() {};
};

struct Bar
{
Bar( Foo* pFoo ) : m_pFoo( pFoo ) {}
void Const() const { m_pFoo->NonConst(); } // Error!
private:
DeepPtr<Foo> m_pFoo;
};

Unfortunately, the disabled copy constructor and assignment operator
mean that such a pointer cannot be used in a standard container.

Cheers! --M


这篇关于指针数据成员的const正确性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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