C ++:通过引用传递或使用私有实例变量

时间:2012-12-12 23:44:37

标签: c++ recursion parameter-passing pass-by-reference instance-variables

这样做的最佳方式是:我收到了一个大型集合类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;
    }
}

2 个答案:

答案 0 :(得分:2)

如果您只是存储一个传递给类方法的参数,以便在方法调用期间访问它,我会说这是一种代码气味,即表明某些东西已经关闭。

类上的成员变量定义了它的状态,在这种情况下,Lexicon似乎不属于该类的状态,因为它只是在单个函数调用期间使用(从外部角度看),并且未使用然后是上课。

因此,在您提供的两个选项中,我显然更愿意传递参数。

第三种选择是将引用添加为构造函数参数。

第四个选项是创建一个包含'RecursiveMnemonics','DigitLetters'和'containsPrefix'的新类,并让新类将Lexicon作为构造函数参数引用。然后通过'ListCompletions'在堆栈上创建新类。

答案 1 :(得分:2)

这里有两条评论。

  1. 确保Lexicon引用为const。我觉得其他任何事情都会让人产生怀疑。
  2. 你的直觉是正确的 - 最好将Lexicon作为参数传递,而不是将其存储在私有成员中。但是,如果所有参数传递都过多,则成员实例可以是一个选项。只有你可以选择那里最好的权衡。
  3. 奖金评论:为什么让DigitLetters会员发挥作用?它没有引用任何成员数据 - 因此,它会更好地作为自由函数。