рекурсия — C ++: передача по ссылке или использование личных переменных экземпляра

Каков наилучший способ сделать это: я получил большой класс коллекции ListCompletions(string digits, Lexicon & lex) (Lex). Мне нужно получить доступ к нему в containsPrefix(string prefix)метод. Я получил возможность передать лексикон по ссылке между методами (некоторых методов, где я его не использую), или я могу сделать его копию в containsPrefix(string prefix) сохраняя его как частную переменную экземпляра.

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

#include "CellPhoneMindReading.h"
void CellPhoneMindReading :: ListCompletions(string digits, Lexicon & lex)
{
//cout << lex.contains("fedora") << endl;

RecursiveMnemonics("", "72");
}/*
* Function: containsPrefix
* Usage: containsPrefix(prefix);
* ----------------------------------------
* This function returns the given prefix passed as argument if it
* is found in the Lexicon database. prefixes that are not found
* is discarded and the return value is a empty string.
*/
string CellPhoneMindReading :: containsPrefix(string prefix)
{
if (
return "";
}/*
* Function: RecursiveMnemonics
* Usage: RecursiveMnemonics(prefix, rest);
* ----------------------------------------
* This function does all of the real work for ListMnemonics and
* implements a more general problem with a recursive solution
* that is easier to see. The call to RecursiveMnemonics generates
* all mnemonics for the digits in the string rest prefixed by the
* mnemonic string in prefix. As the recursion proceeds, the rest
* string gets shorter and the prefix string gets longer.
*/
void CellPhoneMindReading :: RecursiveMnemonics(string prefix, string rest)
{
if (rest.length() == 0)
{
cout << prefix << endl;
containsPrefix(prefix);
}
else {
string options = DigitLetters(rest[0]);
for (int i = 0; i < options.length(); i++)
{
RecursiveMnemonics(prefix + options[i], rest.substr(1));
}
}
}/*
* Function: DigitLetters
* Usage: digits = DigitLetters(ch);
* ---------------------------------
* This function returns a string consisting of the legal
* substitutions for a given digit character. Note that 0 and
* 1 are handled just by leaving that digit in its position.
*/
string CellPhoneMindReading :: DigitLetters(char ch)
{
switch (ch) {
case '0': return ("0");
case '1': return ("1");
case '2': return ("ABC");
case '3': return ("DEF");
case '4': return ("GHI");
case '5': return ("JKL");
case '6': return ("MNO");
case '7': return ("PRS");
case '8': return ("TUV");
case '9': return ("WXY");
default: cout << "Illegal digit" << endl;
}
}

1

Решение

Два комментария здесь.

  1. Убедитесь, что ссылка на лексикон постоянна. Все, что я думаю, показалось бы подозрительным.
  2. Ваш инстинкт верен — предпочтительнее передать Лексикон в качестве аргумента, чем хранить его в приватном члене. Однако, если все эти аргументы передаются слишком много, экземпляр члена может быть опцией. Только вы можете выбрать лучший компромисс там.

Бонусный комментарий: зачем делать функцию члена DigitLetters? Он не ссылается ни на какие данные-члены — таким образом, он был бы лучше как свободная функция.

2

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

Если вы просто сохраните аргумент, переданный методу класса для доступа к нему во время вызова метода, я бы сказал, что это запах кода, то есть указание на то, что что-то не так.

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

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

Третий вариант — добавить ссылку в качестве аргумента конструктора.

Четвертым вариантом будет иметь новый класс, который содержит ‘RecursiveMnemonics’, ‘DigitLetters’ и ‘containsPrefix’, и этот новый класс будет принимать ссылку на Lexicon в качестве аргумента конструктора. Новый класс затем создается в стеке с помощью ListCompletions.

2

По вопросам рекламы [email protected]