10

听起来可能很愚蠢。在 C++prime 第 5 版 P258 中,它说:

默认情况下,this 的类型是指向类类型的非常量版本的 const 指针。例如,默认情况下,Sales_data 成员函数中 this 的类型是 Sales_data *const。

我可以理解,对于 this* 是一个 const 指针,这意味着它指向的对象一旦初始化就不能改变。但是它说:

虽然这是隐含的,但它遵循正常的初始化规则,这意味着(默认情况下)我们不能将它绑定到 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 的指针,我们的函数会更加灵活。

我想知道灵活性是什么?你能给我看一些例子吗?

4

5 回答 5

13

对于初学者来说,this通常被描述为一个常量指针。

但是,this实际上是指针类型的prvalue(纯右值)。您不能将任何东西分配给基本类型的纯右值,这意味着this.

的确切类型this取决于方法的 cv 限定。一个经验法则是 cv-qualification 只是简单地添加到通常的指针类型之前 - 即,如果方法Class标记为const,则类型为const Class*

如果编译器可以很好地编译它是否有'const',为什么这很重要?

当(且仅当)指针类型为thisisconst时,您不能修改该类的成员。

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的方法,这通常是必需的。

于 2014-12-22T16:23:11.580 回答
7

根据 C++ 标准(9.3.2 this 指针)

1 在非静态 (9.3) 成员函数的主体中,关键字 this 是纯右值表达式,其值是调用该函数的对象的地址。类 X 的成员函数中 this 的类型是 X*。如果成员函数声明为 const,则 this 的类型为 const X*,如果成员函数声明为 volatile,则 this 的类型为 volatile X*,如果成员函数声明为 const volatile,则 this 的类型为 const挥发性 X*。

如您所见,没有任何内容this具有ClassTYpe * const. ClassType const * const它是一个纯右值,除了可以调用非 const 成员函数的类类型的纯右值外,不能修改为任何纯右值。

至于你,那么你混合两种类型,一个常量指针和一个指向常量数据的指针。例如这个声明

const ClassType *p;

没有声明一个常量指针。所以指针本身可能没有初始化。另一方面,这个声明

ClassTYpe * const p = new ClassTYpe;

声明一个常量指针,并且指针本身应初始化为任何其他常量。

至于你书中的这句话

毕竟,isbn 的主体不会改变 this 指向的对象,所以如果 this 是指向 const 的指针,我们的函数会更加灵活

那么这意味着最好用限定符 const 定义函数。在这种情况下,可以为常量和非常量对象调用它。否则它可能只被称为非常量对象,因为在函数中指针类型this不是const ClassTYpe *

于 2014-12-22T16:25:11.593 回答
5

“我可以理解,对于 this* 是一个 const 指针,这意味着它指向的对象一旦初始化就不能改变。但是它说:”

不,你搞错了。作为const 指针意味着,您不能像更改指针值本身this一样

 class MyClass {
      void foo() {
          MyClass a;
          this = &a; // <<< Compiler error
      }
 }

的类型this实际上显示为

 MyClass * const this;

对于const实例或参考

 MyClass const * const this;

请注意,这与

 const MyClass* some_const_instance_pointer;
于 2014-12-22T16:22:59.703 回答
5

“灵活性”是您可以const在任何对象上调用函数,无论是否为常量。您不能在对象(或引用/指针)上调用非const函数。constconst

所以以下将失败:

const Test c;
cout << a.getint() << " ";   // ERROR: non-const function
cout << a.getstr() << endl;  // OK: const function

除了这种灵活性之外,声明成员函数const也是一个好主意,因为这将防止您意外修改函数中不应该修改的对象。

于 2014-12-22T16:23:06.800 回答
4

两个问题两个答案。

this无法重新分配指针。这就是const在这种情况下的意思。您可以更改指向的对象的内容,this但不能更改它指向的对象。

创建方法的额外灵活性const在于它可以用于const非 const 对象和对象。不能在const对象上使用非常量方法。

例子:

class A {
    int a;
    public:
    int method() const {
        return a;
    }
};

void f() {
    A a;
    const A ca;

    a.method();
    ca.method();
}
于 2014-12-22T16:23:41.083 回答