繁体   English   中英

“ this”指针如何用作成员函数的参数

[英]How is the 'this' pointer used as an argument of a member function

我有这个简单的课程

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的参数?

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

9.3.2 this指针[class.this]

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

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

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

请记住,(非静态)成员函数不是函数。 您不能只打电话给他们。 相反,您必须始终在实例对象上调用它们。 该实例对象是成员函数的隐式参数,但从未明确说明。 可通过this表达式在函数内部使用。

如果隐式instance参数结合到恒定对象,那么类型thisT const * ,以及仅被限定为成员函数const可以被调用。 volatile类似,也有类似的规则将隐式实例参数绑定到右值引用。

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

由于您的问题是:

this指针如何用作func2的参数

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

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

static成员函数没有this指针。

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM