Почему мой тип возврата не имеет смысла? - PullRequest
11 голосов
/ 26 марта 2009

Я пытаюсь использовать тип возврата const MyClass * const. Однако я получаю предупреждение:

Предупреждение: # 815-D: спецификатор типа для возвращаемого типа не имеет смысла.

Это недопустимый тип? Мне нужен указатель, который нельзя изменить, и я хочу, чтобы то, на что он указывает, также не изменилось.

Ответы [ 6 ]

22 голосов
/ 26 марта 2009

Сам указатель имеет тип значения, поэтому нет смысла делать его константным. То, что делает функция-вызывающая функция с возвращенным значением, не может быть ограничено вызываемой функцией. Это похоже на попытку определить что-то вроде:

const int getInt();

getInt (), в этом случае, просто возвращает значение типа int (не ссылка). Он идет в регистр, затем функция вызывающего получает его и делает с ним все, что хочет.

5 голосов
/ 26 марта 2009

Я согласен с ответом Джулиано, вы хотите, чтобы константа указателя была на сайте вызова.

Лучший способ сделать то, что вы ищете, это заставить вашу функцию возвращать константную ссылку на объект:

const MyClass& getMyClass()
{ 
  return myClass;
}

По определению ссылки не могут быть изменены, поэтому вам будет лучше.

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

// function definition
const MyClass* createMyClass()
{ 
  return new MyClass("I Love C++");
}

// use of a const pointer to a MyClass which is const
const MyClass* const myClassInstance = creatMyClass();
4 голосов
/ 26 марта 2009

Один простой способ убедиться, что вы определяете нужный тип возвращаемого значения, это всегда добавлять модификаторы справа (в отличие от левой) стороны исходного типа.

MyClass                 // MyClass object
MyClass const           // MyClass object which can't be modified
MyClass const &         // reference of an unmodifiable MyClass object 
MyClass const *         // pointer to an unmodifiable MyClass object
MyClass const * const   // unmodifiable pointer to an unmodifiable MyClass object
MyClass const * const & // reference of an unmodifiable pointer to an unmodifiable MyClass object

Это должно помочь убедиться, что ваши типы возвращаемых данных больше никогда не будут бессмысленными:)

4 голосов
/ 26 марта 2009

Почему вас волнует изменение указателя? Делать это все равно что сказать:

const int f() {
   ...
}

Значение, возвращаемое функцией f (), является копией - его изменение ничего не меняет, поэтому нет смысла делать его постоянным.

0 голосов
/ 27 марта 2009

Зачем возвращать постоянное значение? Подумайте над следующим (и, пожалуйста, извините, не названные имена переменных):

struct A { int a; };

A operator+(const A& a1, const A& a2) 
{
    A a3 = { a1.a + a2.a };
    return a3;
}

Учитывая это объявление operator+, я могу сделать следующее:

A a = {2}, b = {3}, c = {4}, d = ((a+b) = c);

Правильно, я просто назначил временный A, который был возвращен operator+. Результирующее значение d.a равно 4, а не 5. Изменение типа возвращаемого значения с operator+ на const A предотвращает это назначение, в результате чего выражение (a+b) = c вызывает ошибку компилятора.

Если я пытаюсь присвоить указатель или целое число, возвращаемое функцией, мой компилятор (MSVC) генерирует ошибку «левый операнд должен быть l-значением», что, по-видимому, согласуется с тем, что компилятор ARM сообщает вам, что константа Указатель не имеет смысла - указатель не может быть назначен в любом случае. Но для классов / структур, очевидно, можно присвоить неконстантные возвращаемые значения.

0 голосов
/ 26 марта 2009

квалификатор const ничего не значит, потому что вы возвращаете указатель

...