为啥允许我从 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

【讨论】:

@MattSwarthout const 表示您不能修改调用非常量成员函数的数据成员。你的数据成员是一个指针,你没有修改它......你只需要小心指针。 我现在明白了,但我看不出“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() ?的主要内容,如果未能解决你的问题,请参考以下文章

C++类和对象(this指针6个默认成员函数const成员)

成员函数

const 成员函数的语义是啥?

const常对象成员与常成员函数

测试页面

类的成员函数后面加const有什么用(c++常问问题六)