为啥允许我从 const 成员函数调用 this->deviceContext->map() ?
Posted
技术标签:
【中文标题】为啥允许我从 const 成员函数调用 this->deviceContext->map() ?【英文标题】:Why am I allowed to call this->deviceContext->map() from a const member function?为什么允许我从 const 成员函数调用 this->deviceContext->map() ? 【发布时间】:2013-02-20 22:43:47 【问题描述】:我不明白为什么允许这样做:
void Renderer::UpdateTextureFromArray(unsigned int* colors, unsigned int size, TextureData* textureData) const
D3D11_MAPPED_SUBRESOURCE ms;
this->deviceContext->Map(textureData->texture, 0, D3D11_MAP_WRITE_DISCARD, NULL, &ms);
memcpy(ms.pData, colors, sizeof(unsigned int) * size * size);
this->deviceContext->Unmap(textureData->texture, 0);
我将 UpdateTextureFromArray 函数设为 const,但我仍然可以对其成员调用非 const 函数?
在这种情况下,将函数标记为 const 对我来说是不是很糟糕?
编辑:澄清一下,如果我有这样的 const 函数,是不是对社会“撒谎”?在完美的世界中,这段代码不会编译,对吧?
【问题讨论】:
【参考方案1】:推测deviceContext
是指针数据成员,所以const
方法不能修改指针。但是允许修改指针指向的对象:
struct Bar
void bar() // non const method
;
struct Foo
Foo() : p(0)
void foo() const p->bar(); // const method calling non-const method of Bar
Bar* p;
;
int main()
const Foo f;
f.foo(); // OK, Foo::p is not modified
【讨论】:
@MattSwarthoutconst
表示您不能修改调用非常量成员函数的数据成员。你的数据成员是一个指针,你没有修改它......你只需要小心指针。
我现在明白了,但我看不出“const”如何提供任何形式的保护或保证,如果它不检查这一点。当您取消引用“this”时,它会返回一个 const“this”,并且仍然不允许您调用 const 函数。为什么取消引用自己的成员不做同样的事情?
@MattSwarthout this
是一种特殊情况,作为隐式第一个参数传递给成员函数。当函数为const
时,this
指向一个const
对象。
即在 const 成员函数 this
中具有类型 const Foo* const
,在非 const 成员函数中它具有类型 Foo* const
这很有意义,只是与您的期望不同。指针指向的类型由类型系统设置。指向Foo
的指针不会因为您在const
成员中访问它,或者绑定到它的const 引用并使用它而成为指向const Foo
的指针。【参考方案2】:
您不是在其成员上调用非常量函数,而是在取消引用其成员(不会修改它,因此允许使用 const
指针完成)然后调用非该取消引用结果的 const 成员。
【讨论】:
我明白了。我只是假设常量会通过取消引用传播。 不,取消引用Foo* const
的结果与取消引用Foo*
的结果相同,两者都是Foo&
。【参考方案3】:
您没有在其成员上调用非常量函数,您正在访问一个指向非常量对象的指针(即常量)。因此,您可以在其上调用非常量函数。
关于样式,const 方法是一种从用户角度不改变对象状态的方法。因此,您必须考虑此指针访问是否执行此操作。有些类是并行化的候选者,在这种情况下,const 方法被认为是安全的并行化方法,因为它们应该没有副作用。
所以要限定一个方法为 const,我建议它:
不适合并行化并且没有用户可见的副作用 是并行化的候选者,但具有适当的同步或完全没有副作用。【讨论】:
以上是关于为啥允许我从 const 成员函数调用 this->deviceContext->map() ?的主要内容,如果未能解决你的问题,请参考以下文章