указатели — тип этого * в переполнении стека

в C ++ prime 5th edition P258 это может звучать глупо:

по умолчанию типом этого является константный указатель на неконстантную версию класса type. Например, по умолчанию типом этого в функции-члене 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.

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

10

Решение

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

Тем не мение, this на самом деле является prvalue (чисто 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-квалификатор по методам позволяет различать методы для const объекты и методы дляconst те, которые часто являются необходимостью.

12

Другие решения

Согласно стандарту C ++ (9.3.2. Указатель this)

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

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

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

const ClassType *p;

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

ClassTYpe * const p = new ClassTYpe;

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

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

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

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

7

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

Так что следующее не получится:

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

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

5

«Я могу понять, что для этого * указатель 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;
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();
}
4
По вопросам рекламы [email protected]