首页 文章

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

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

7 回答

  • 0

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

    9.3.2这个指针[class.this]

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

  • 2

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

  • 7

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

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

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

  • 3

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

    既然你的问题是:

    this指针如何用作func2的参数

    这里引用了一些来自IBM C++ documentation: this pointer的信息:

    关键字this标识一种特殊类型的指针 . 假设您创建了一个名为x的A类对象,而A类具有非静态成员函数f() . 如果调用函数x.f(),则f()体中的关键字this存储x的地址 . 您不能声明this指针或对其进行赋值 . 静态成员函数没有this指针 . 类类型X的成员函数的this指针的类型是X * const . 如果使用const限定符声明成员函数,则类X的该成员函数的this指针的类型是const X * const . const this指针只能用于const成员函数 . 该类的数据成员在该函数中将是常量 . 该函数仍然可以更改值,但需要const_cast才能这样做:void foo :: p()const {
    member = 1; //非法
    const_cast <int&>(member)= 1; //一个不好的做法,但合法
    }
    一种更好的技术是声明成员可变

    .

  • 4

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

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

  • 0

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

相关问题