Почему C ++ позволяет преобразовывать константу в ссылочный аргумент в другом методе? - PullRequest
1 голос
/ 24 декабря 2009
void outputString(const string &ss) {
    cout << "outputString(const string& ) " + ss << endl;
}

int main(void) {
    outputString("constant tranformed to reference argument");
    //! outputString(new string("abc")); new only return pointer to object
    return 0;
}

Поскольку запрещено создавать временные ссылки на объекты, преобразующие в методы, этот синтаксис должен быть бесполезным, но даже усложнять ситуацию. Так почему же C ++ поддерживает такой синтаксис?

РЕДАКТИРОВАТЬ : Честно говоря, я не понял вашего представления. Учитывая приведенный выше пример, мы обычно будем использовать void outputString(const string ss) вместо void outputString(const string &ss). Я думаю, что нормальная вещь - это пройти мимо методы 'value' имеют дело с константами / переменными, а методы 'pass by reference' имеют дело только с переменными. Единственная причина, по которой мы должны использовать const type-id & вместо const type-id для констант, - это эффективность, потому что методы 'pass by reference' принимают только указатели (адреса) переменных констант / объектов примитивов, но методы «передать по значению» должны делать копию.

спасибо.

Ответы [ 4 ]

3 голосов
/ 24 декабря 2009

Разрешается создавать временную ссылку только для параметров const. Если параметр не является константной ссылкой, вы можете изменить данные в методе, не понимая, что ваша ссылка была на временную копию данных, и поэтому это запрещено.

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

2 голосов
/ 29 декабря 2009

Какие у вас альтернативы?

void outputString(const string ss);

Это создаст копию любой переданной строки, даже если тип точно соответствует: накладные расходы, которые на самом деле не нужны!

void outputString(string &ss);

Это позволит изменить переданный аргумент. Мы не хотим этого делать, и C ++ больше не позволяет нам передавать временные данные, чтобы защитить нас от изменения временных (в любом случае эти изменения теряются в следующие моменты).

Итак, то, как вы это делаете, подходит для двух сторон: это позволяет нам передавать невременные строки без их копирования, и это позволяет нам передавать временные строки. И это защищает нас от попыток изменить аргумент. Похоже, хороший компромисс.

2 голосов
/ 24 декабря 2009

Где вы модифицируете ss?

cout << "outputString(const string& ) " + ss << endl;

Эта строка создает временный объект под капотом без изменения объекта const& ss.

Компилятор обычно делает:

string tmp = "outputString(const string& ) " + ss;
cout << tmp << endl;
0 голосов
/ 24 декабря 2009

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

Это важно. В противном случае вам придется написать OutputString (std :: string ("literal")), и это будет очень раздражающим. Можно было бы сделать отдельные перегрузки для метода, принимающего std :: string и char *.

...