如何将'this'指针用作成员函数的参数

时间:2013-04-23 19:57:39

标签: c++

我有这个简单的课程

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对象的非const成员,我的问题是如何进行的 'this'指针用作func2的参数?

7 个答案:

答案 0 :(得分:7)

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

9.3.2 this指针[class.this]

  

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

答案 1 :(得分:4)

您正在看到C ++定义方式的工件。成员函数自动为每个函数添加隐藏的this参数。如果对象是const,那么指针也是const,非const成员函数必须接收非const this指针。

答案 2 :(得分:3)

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

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

如果隐式实例参数绑定到常量对象,则this的类型为T const *,并且只能调用限定为const的成员函数。类似地,对于volatile,并且还存在用于将隐式实例参数绑定到右值引用的类似规则。

答案 3 :(得分:2)

您不能在const对象func2上调用非const函数f

因为你的问题是:

  

如何将this指针用作func2的参数

以下是IBM C++ documentation: this pointer引用的一些信息:

  

关键字this标识一种特殊类型的指针。假设   您创建了一个名为x的类A的对象,而类A有一个   非静态成员函数f()。如果你调用函数x.f(),那么   this正文中的关键字f()存储x的地址。您   无法声明此指针或对其进行赋值。

     

static成员函数没有this指针。

     

类类型的成员函数的this指针的类型   XX* const。如果使用 const限定符声明成员函数,则为该成员的this指针的类型   类X的函数是const 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 
} 
     

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

答案 4 :(得分:1)

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

所以这个:

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 );
}

答案 5 :(得分:0)

你的成员函数func2()应该是const。见here

答案 6 :(得分:0)

在计算机上运行的实际代码中,func2的代码需要知道要查看/执行操作的foo的哪个实例。因此它将一个指针(this)传递给实例。