1

我有这个简单的课程

class foo {
public:
  void func() const;
  void func2();
};

void foo::func() const {}
void foo::func2() {}

int main() {
  const foo f;
  f.func();
  f.func2();
}

当我尝试编译时,我收到此消息:

错误:将 'const foo' 作为 'void foo::func2()' 的 'this' 参数传递会丢弃限定符 [-fpermissive]

我了解 const 对象的非常量成员的使用,我的问题是“this”指针如何用作 func2 的参数?

4

7 回答 7

8

void foo::func2()是非常量,这意味着它可能会改变对象。因此,编译器不允许您为 const 对象调用它。即使您实际上并没有更改func2' 的实现中的任何内容。this是任何非静态成员函数的隐式参数。这就是它如何知道它被调用的确切对象的方式。

9.3.2 this指针[class.this]

1 在非静态 (9.3) 成员函数的主体中,关键字 this 是一个纯右值表达式,其值是调用该函数的对象的地址。

于 2013-04-23T19:59:45.900 回答
4

您将看到 C++ 定义方式的产物。成员函数会自动为每个函数添加一个隐藏this参数。如果对象是,const那么指针也是const如此,并且非常量成员函数必须接收非常量this指针。

于 2013-04-23T20:04:06.407 回答
3

成员函数的实例参数是隐式的。也就是说,它从来不是函数声明的一部分,但它仍然存在。

请记住,(非静态)成员函数不是函数。你不能只打电话给他们。相反,您必须始终在实例对象上调用它们。这个实例对象隐含地是成员函数的一个参数,但从未拼写出来。它可以通过this表达式在函数内部使用。

如果隐式实例参数绑定到一个常量对象,那么类型thisT const *,并且只有符合 as 的成员函数才能const被调用。类似地volatile,对于将隐式实例参数绑定到右值引用也有类似的规则。

于 2013-04-23T20:03:47.477 回答
2

您不能func2在 const object 上调用非常量函数f

因为你的问题是:

指针如何this用作 func2 的参数

以下是从IBM C++ 文档中引用的一些信息:此指针:

关键字this标识一种特殊类型的指针。假设您创建了一个名为xclass的对象A,并且 classA有一个非静态成员函数f()。如果调用该函数,主体中x.f()的关键字存储的地址。您不能声明 this 指针或对其进行赋值。thisf()x

static成员函数没有指针this

类类型this的成员函数的指针的类型 XX* const。如果使用 const限定符声明成员函数,则该成员函数的指针类型为thisclass 。Xconst X* const

const this指针只能与 一起使用const member functions。类的数据成员将在该函数中保持不变。该函数仍然能够更改值,但需 const_cast要这样做:

void foo::p() const{    
    member = 1;                       // illegal    
    const_cast <int&> (member) = 1;   // a bad practice but legal 
} 

更好的技术是声明成员可变

.

于 2013-04-23T19:59:42.207 回答
1

在 OOP 中(通常),编译器将所有实例方法静默转换为静态函数,并添加指向包含实例状态(即)的结构的指针this作为隐藏的第一个参数。

所以这:

class Foo
{
    private:
        Int32 _bar;

    public:
        void Add(Int32 x)
        {
            this->_bar += x;
        }
};

void Main()
{
    Foo foo;
    foo.Add(3);
}

实际上是这样实现的:

struct Foo {
    Int32 _bar;
}

static void Foo_Add(Foo *thisPtr, Int32 x)
{
    thisPtr->_bar += x;
}

void Main()
{
    Foo foo;
    Foo_Add( &foo, 3 );
}
于 2013-04-23T20:04:00.583 回答
0

您的成员函数 func2() 应该是 const。看这里

于 2013-04-23T20:00:27.297 回答
0

In the actual code as run on the computer, the code for func2 needs to know which instance of foo to look at/do things to. So it is passed a pointer (this) to the instance.

于 2013-04-23T20:05:23.587 回答