C++ 中 this* 的类型
Posted
技术标签:
【中文标题】C++ 中 this* 的类型【英文标题】:the type of this* in C++ 【发布时间】:2014-12-22 16:15:50 【问题描述】:这听起来可能很愚蠢。在 C++prime 第 5 版 P258 中,它说:
默认情况下,this 的类型是指向类类型的非常量版本的 const 指针。例如,默认情况下,Sales_data 成员函数中 this 的类型是 Sales_data *const。
我可以理解 this* 是一个 const 指针,这意味着它指向的对象一旦初始化就不能改变。但是它说:
虽然这是隐式的,但它遵循正常的初始化规则,这意味着(默认情况下)我们不能将 this 绑定到 const 对象。
但我写了以下代码,它仍然编译得很好:
class Test
public:
Test() = default;
Test(const string &s): teststr(" ") ;
Test(int a) : testint(a) ;
Test(const string &s, int a): teststr(s), testint(a) ;
string getstr() const return teststr; ;
int getint() return testint; ; //there is no const here
private:
string teststr;
int testint = 0;
;
int main()
Test a("abc",2);
cout << a.getint() << " ";
cout << a.getstr() << endl;
cout << endl;
return 0;
所以我的问题是: 如果编译器可以很好地编译它是否有'const',为什么这很重要? 然后书上说:
毕竟 isbn 的主体不会改变 this 指向的对象,所以如果 this 是指向 const 的指针,我们的函数会更灵活。
我想知道灵活性是什么?你能给我举几个例子吗?
【问题讨论】:
这本书具有误导性。this
不是“常量指针”。它是一个关键字,在评估时会产生一个合适指针类型的纯右值。既然是prvalue,就不能修改,就像不能说(1 + 2) = 3
一样。
您混淆了“const 指针”(不能指向不同对象的指针)和“指向 const 的指针”(指向不允许更改的对象的指针指针)。
至于你想要的例子,把你的main()
的第一行改成const Test a("abc",2);
,你会注意到你不能再调用getint()
但是你可以 继续拨打getstr()
。不改变对象的方法应该声明为const
,因为这样它们就可以在给定const
对象(或引用/指向const
对象)时使用。
您的引用特别指出“默认情况下,this 的类型是一个 const 指针指向类类型的非 const 版本。例如,默认情况下,this 的类型在 Sales_data 成员函数中是 Sales_data *const"
你一直在输入this*
这不是一回事。请简单的this
。
【参考方案1】:
对于初学者来说,this
通常被描述为一个常量指针。
然而this
实际上是一个指针类型的prvalue(纯右值)。您不能将任何东西分配给基本类型的纯右值,这意味着 this
的“常量性”。
this
的确切类型取决于方法的 cv 限定。经验法则是 cv-qualification 只是简单地添加到通常的指针类型之前 - 即,如果 Class
的方法标记为 const
,则类型为 const
Class*
。
如果编译器可以编译它是否有 'const' 或 不是,这有什么关系?
如果(且仅当)this
的指针类型为const
,则不能修改该类的成员。
Class const* ptr; // ptr->data is also const, not modifiable through this pointer
Class* ptr; // ptr->data isn't const - can be modified.
方法上的const
-qualifier 允许您区分const
对象的方法和非const
对象的方法,这通常是必需的。
【讨论】:
【参考方案2】:根据 C++ 标准(9.3.2 this 指针)
1 在非静态 (9.3) 成员函数的主体中,关键字 this 是一个纯右值表达式,其值是对象的地址 该函数被调用。成员函数中 this 的类型 X 类是 X*。如果成员函数声明为 const,则其类型 this 是 const X*,如果成员函数声明为 volatile,则 this 的类型是 volatile X*,并且如果声明了成员函数 const volatile,this的类型是const volatile X*。
如您所见,没有任何内容表明 this
的类型为 ClassTYpe * const
或 ClassType const * const
。它是一个纯右值,除了可以调用非 const 成员函数的类类型的纯右值外,不能修改为任何纯右值。
至于你,你混合了两种类型,一个常量指针和一个指向常量数据的指针。 比如这个声明
const ClassType *p;
不声明常量指针。所以指针本身可能没有初始化。另一方面是声明
ClassTYpe * const p = new ClassTYpe;
声明一个常量指针,并且指针本身应该被初始化为任何其他常量。
至于你书中的这句话
毕竟,isbn 的主体不会改变 this 的对象 点,所以如果这是一个指针,我们的函数会更灵活 为常量
那么这意味着最好用限定符const来定义函数。在这种情况下,可以为常量和非常量对象调用它。否则它可能只为非常量对象调用,因为在函数中this
的指针类型不是const ClassTYpe *
。
【讨论】:
"它是一个纯右值,不能被修改为任何纯右值" 这只适用于非类类型的纯右值,所以 "any" 错了。 @Lightness Races in Orbit 您可以为类类型的prvlaue 调用非常量成员函数,但您不能直接更改该类的数据成员。 正确,但您可以通过调用成员函数来做到这一点。说你不能修改对象是完全错误的。【参考方案3】:“灵活性”是您可以在任何对象上调用const
函数,无论是否为常量。您不能在 const
对象(或指向 const
的引用/指针)上调用非 const
函数。
所以下面会失败:
const Test c;
cout << a.getint() << " "; // ERROR: non-const function
cout << a.getstr() << endl; // OK: const function
除了这种灵活性之外,声明成员函数const
也是一个好主意,因为这样可以防止您在不应该修改的函数中意外修改对象。
【讨论】:
【参考方案4】:“我可以理解 this* 是一个 const 指针,这意味着它所指向的对象一旦初始化就不能改变。但是它说:”
不,你搞错了。作为this
一个 const 指针 意味着,你不能像改变指针值本身一样
class MyClass
void foo()
MyClass a;
this = &a; // <<< Compiler error
this
的类型实际上显示为
MyClass * const this;
对于const
实例或引用
MyClass const * const this;
Note this is different from
const MyClass* some_const_instance_pointer;
【讨论】:
"注意这与"你错了。完全没有区别。:) 虽然你更新了你的帖子,但我看不出有什么不同。:)【参考方案5】:两个问题两个答案。
this
指针无法重新分配。在这种情况下,这就是 const
的含义。您可以更改this
指向的对象的内容,但不能更改它指向的对象。
创建方法const
的额外灵活性在于它可以用于const
和非常量对象。不能在 const
对象上使用非常量方法。
例子:
class A
int a;
public:
int method() const
return a;
;
void f()
A a;
const A ca;
a.method();
ca.method();
【讨论】:
以上是关于C++ 中 this* 的类型的主要内容,如果未能解决你的问题,请参考以下文章
C++ _ const的用法,特别是用在函数前面与后面的区别!
C++:对象和类|| this指针对象数组类作用域抽象数据类型章末总结