Тип этого * в С++

это может звучать глупо. В С++ prime 5th edition P258 говорится:

по умолчанию, тип этого является указателем константы для версии nonconst класса. Например, по умолчанию тип этого в функции члена Sales_data является Sales_data * const.

я могу понять, что для этого * является указателем 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 не изменяет объект, на который это указывает, поэтому наша функция будет более гибкой, если бы это был указатель на const.

и мне интересно, что такое гибкость? Не могли бы вы показать мне несколько примеров?

Ответ 1

Для новичков this часто отображается как постоянный указатель.

Однако this на самом деле является значением prvalue (pure rvalue) типа указателя. Вы не можете назначить что-либо для значений основного типа, что подразумевает "константу" this.

Точный тип this зависит от cv-квалификации метода. Эмпирическое правило состоит в том, что cv-квалификация просто добавляется к обычному типу указателя - то есть, если метод Class отмечен const, тогда тип const Class*.

если компилятор может скомпилировать его в порядке, есть ли 'const' или не, почему это важно?

Если (и только если) тип pointee 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 on позволяют различать методы для const объектов и методов для non const, что часто является необходимостью.

Ответ 2

В соответствии со стандартом С++ (9.3.2 Этот указатель)

1 В теле нестатической (9.3) функции-члена ключевое слово this является выражением prvalue, значением которого является адрес объекта для который вызывается функцией. Тип этого в членной функции класс X является X *. Если функция-член объявлена ​​const, тип это const X *, если функция-член объявлена ​​изменчивой, тип этого является изменчивым X *, и если объявлена ​​функция-член const volatile, тип этого - const volatile X *.

Как вы видите, ничего не сказано, что this имеет тип ClassTYpe * const of ClassType const * const. Это prvalue, которое не может быть изменено как любое prvalue, за исключением того, что для prvalue типа класса вы можете вызывать неконстантные функции-члены.

Как и для вас, вы смешиваете два типа указателя константы и указатель, указывающий на постоянную информацию. Например, это объявление

const ClassType *p;

не объявляет постоянный указатель. Таким образом, сам указатель не может быть инициализирован. С другой стороны, декларация thsi

ClassTYpe * const p = new ClassTYpe;

объявляет константный указатель, и сам указатель инициализируется как любая другая константа.

Что касается этой цитаты из вашей книги

в конце концов, тело isbn не изменяет объект, к которому это точек, поэтому наша функция была бы более гибкой, если бы это был указатель к const

Тогда это означает, что было бы лучше определить функцию с квалификатором const. В этом случае его можно было бы вызвать для постоянных и непостоянных объектов. В противном случае он может быть вызван только для -не константных объектов, потому что внутри функции тип указателя this не const ClassTYpe *.

Ответ 3

"я могу понять, что для этого * является указателем const, который означает, что объект, который он указывает после инициализации, не может изменить. Но тогда он говорит:"

Нет, вы ошиблись. Будучи this указателем const, вы не можете изменить значение указателя как

 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;

Ответ 4

"Гибкость" заключается в том, что вы можете вызвать функцию const на любом объекте, постоянном или нет. Вы не можете вызвать функцию const для объекта const (или ссылку/указатель на const).

Таким образом, следующее:

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

Как и эта гибкость, объявление функции-члена const является хорошей идеей, поскольку это предотвратит случайную модификацию объекта в функции, которая не должна быть.

Ответ 5

Два ответа на два вопроса.

Указатель this нельзя переназначить. В этом случае это означает const. Вы можете изменить содержимое объекта, на который указывает this, но вы не можете изменить, на какой объект он указывает.

Дополнительная гибкость при создании метода const заключается в том, что он может использоваться как для объектов const, так и для неконстантных объектов. Метод non-const не может использоваться для объекта const.

Пример:

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

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

    a.method();
    ca.method();
}