2015-02-22 4 views
0

Я новичок в C++, поэтому, пожалуйста, несите меня, если это глупый вопрос.Этот метод оценивает пустую строку?

Метод ниже, кажется, создает строку с именем reversePhrase но без начального значения, а затем использовать его phrase.evalPalindrome(reversePhrase):

void testForPalindrome(string origPhrase) 
{ 
    string reversePhrase; 
    bool isPalindrome; 
    Palindrome phrase(origPhrase); 


    if (phrase.evalPalindrome(reversePhrase)) 
    { 
     cout << "This phrase IS a palindrome!" << endl; 
    } 
    else 
    { 
     cout << "This phrase is NOT a palindrome." << endl; 
    } 
    cout << "Original phrase: " << origPhrase << endl; 
    cout << "Reverse phrase: " << reversePhrase << endl << endl; 
} 

В Java это создаст исключения нулевого указателя. Но я проанализировал метод, который вызывается, и похоже, что он принимает адрес строки.

bool Palindrome::evalPalindrome (string& reversePhrase) 
{ 
    // code 
} 

Но я не понимаю, как это работает. Выполняет ли начальный string reversePhrase; память reversePhrase? Если да, то как вызывающая функция может затем распечатать reversePhrase, которая была изменена из другой функции (код не отображается, но он изменен из другой функции).

Кажется, что писать код таким образом трудно читать.

+0

'String reversePhase = new String();' в Java равно 'string * reversePhase = new string();' в C++. В Java, 'reversePhase' в этом случае является указателем, поэтому вы получаете исключение, если вы ему ничего не присваиваете. – farukdgn

ответ

2

В java это создало бы исключение нулевого указателя.

Это потому, что Java - это другой язык с различным синтаксисом создания объекта.

В C++, как только вы написали string reversePhrase, этот объект был полностью сформирован и готов к работе.


Но я проанализировал метод, который вызывается, и выглядит она принимает адрес строки.

Нет, он принимает ссылку на строку! И это почему область вызова может позже увидеть измененную строку!

+0

В классе нам сказали, что '&' является оператором 'addressOf'. Поэтому я просто предположил, что это то, что передавалось. –

+0

@inquisitor: [Символ '&' означает разные вещи в зависимости от того, где вы его видите! Рассмотрим, например, двоичный файл AND.] (Http://stackoverflow.com/a/28368782/560648) –

+0

Точка, взятая на '&'! Причина, по которой это меня путала, состоит в том, что в java этот код никогда не будет компилироваться (я понимаю, что они разные языки). –

1

Вы не создаете указатель, а объект типа string. Он никогда не назначается, поэтому он должен быть пустой строкой "". Получение адреса к нему будет работать нормально, поскольку это действительный объект.

Я не уверен, что эта функция будет работать.

+0

Почему, по-вашему, функция «не будет работать»? –

+0

Я предполагаю, что меня смущает код. Является ли фраза.evalPalindrome (reversePhrase), дающая reversePhrase его значение? Когда reversePhrase когда-либо получает значение? – marsh

+0

Это не так. Откройте свою книгу на C++ в главе о _references_! –

2

string& reversePhrase не объявляет evalPalindrome, чтобы принять адрес строки. Он объявляет, что функция принимает ссылку на строку. (Декларирование его string* будет означать адрес строки, иначе указатель на строку.)

В C++, при инициализации строки без аргументов:

string reversePhrase; 

он создает пустой string, поэтому reversePhrase равен "". Таким образом, это не пустая строка, просто пустая, которую вы можете безопасно передать по ссылке на функцию evalPalindrome, которая затем сможет изменить исходный объект строки, переданный ему.

+0

Я вижу. Таким образом, метод 'evalPalindrome (string & reversePhrase)' просто модифицирует переданную ссылку и поэтому его можно использовать в конце вызывающего метода? –

+0

@inquisitor Да, точно, передача по не-const-ссылке позволяет функции изменять исходный объект. – emlai

+0

Так много теперь имеет смысл. Согласитесь ли вы, что это затрудняет чтение кода? И, наверное, поэтому я вижу, что 'const' так много использовал в C++ –

1

Что здесь происходит, так называется пропуск по ссылке. Обычно, когда вы передаете переменную в C++, ее копия выполняется. Вот почему, когда вы запускаете ниже, вы получите «A», «B», «A».

int main(){ 
    string s = "A"; 
    cout << s << endl; 
    cngLetter(s); 
    cout << s << endl; 
} 

void cngLetter(string s){ 
    s = "B"; 
    cout << s << endl; 
} 

Если вы пройдете по ссылке, то она обновит его на основной теме. Далее будет печатать «A», «B», «B»

int main(){ 
    string s = "A"; 
    cout << s << endl; 
    cngLetter(s); 
    cout << s << endl; 
} 

void cngLetter(string& s){ 
    s = "B"; 
    cout << s << endl; 
} 

Обратите внимание, что только один символ был добавлен к этому, &, который вызывает передачу по ссылке, т.е. не копировать, а вместо этого память адрес. Мне не нужно набирать много в этом посте, так как вы можете прочитать об этом here

string s не неуправляемая память, поэтому, если вы не назначили ее сначала, то вместо этого вы получите «», «B», «B»

int main(){ 
    string s; 
    cout << s << endl; 
    cngLetter(s); 
    cout << s << endl; 
} 

void cngLetter(string s){ 
    s = "B"; 
    cout << s << endl; 
} 

в основном, строка, которая не дала щёток значение просто пустая строка.

+0

«Тема» - это не то слово здесь. Ссылки и адреса памяти - это не одно и то же. «Неуправляемый» означает что-то еще. –

+0

Получает точную точку. – David

+0

Несомненно, если «точка пересечения» означает «учит неправильной терминологии, распространяет дезинформацию и сбивает всех с толку». :-) –

-2

Оператор '&' в этом контексте является синтаксической конфеткой для '*'. В методе evalPalindrome, в то время как reversePhrase передается как указатель, он ВСЕГДА разыменовывается. Это делает невозможной обычную ошибку, а не разыменование указателя. Вы правы, что это может привести к запутыванию кода, поскольку значение передаваемого значения может быть изменено подобно тому, как оно было передано в качестве указателя, за исключением того, что вызывающая функция не имеет указаний на то, что она передается в виде указателя если вы специально не смотрите на подпись метода.

+0

'&' здесь не оператор, и это не «синтаксическая конфета для * *», хотя я ценю сравнение, которое вы пытаетесь сделать.В конечном счете, однако, вы фиксируетесь на деталях потенциального _implementation_ и, тем самым, распространяете опасную дезинформацию. –

+0

Объекты '&' не занимают дополнительной памяти, в отличие от объекта '*', состоящего из (обычно) 4 байта. '&' - просто другое имя для назначенного ему объекта. Кажется, я мог бы назвать тебя Рэнди, или Камради, которые ты и есть. – David

+0

@David: На самом деле не указано, имеет ли ссылка память ('[C++ 11: 8.3.2/4]'), но это утечка абстракции, необходимая тем фактом, что ссылка, хранящаяся как элемент данных класса будет занимать место. –

Смежные вопросы