我有这个简单的课程
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的参数?
答案 0 :(得分:7)
void foo::func2()
是非常量,这意味着它可能会更改对象。因此编译器不允许您为const对象调用它。即使你实际上没有改变func2
的实现中的任何内容。 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
指针的类型X
,X* 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
)传递给实例。