1

私は最近このクラスに出くわし、getter と setter がどのように実装されているかに驚きました。

私はこれまでにこれに遭遇したことがなく、いくつかのセカンドオピニオンを歓迎します.

これは良いパラダイムだと思いますか?悪いですか?それは悪ですか?

ヘッダ:

    class Tool
{
public:
    Tool();
    virtual ~Tool();

    bool setName(const std::string &name);
    bool getName(std::string &name) const;

    void clearName();

private:
    std::string m_name;
    bool m_nameSet;

};

cpp ファイル:

#include "Tool.h"

Tool::Tool()
: m_name("")
, m_nameSet(false)
{
}


Tool::~Tool()
{
}


bool Tool::setName(const std::string &name)
{
    m_name = name;
    m_nameSet = true;
    return (m_nameSet);
}    

bool Tool::getName(std::string &name) const
{
    bool success = false;
    if (m_nameSet)
    {
        name = m_name;
        success = true;
    }
    return (success);
}
4

3 に答える 3

2

ゲッターに選択した方法は一般的ではありません。プログラマーはreturnゲッターからのデータを好みます

std::string getName() const;

前に設定されたアイテム、または初期データを持つアイテムをゲッターで再チェックする必要があるのはなぜですか? データを検証する場合は、セッターで検証します。

ただし、「前に設定された名前」として値を返すことを主張する場合は、次の方法で3番目のメソッドを作成できますbool isNameSet() const;

于 2013-03-05T12:16:49.600 に答える
2

これは、関数が失敗したかどうかを確認するためにステータス コードを返すのが通常である C によく似ています。

次に、名前が設定されているかどうかを確認するためのより良い方法もあります。boost::optional を使用することもできます。これは、名前が常に設定されているとは限らないという意図を宣言するためのより良い方法です。

ただし、 std::string をパラメーターとして受け取るコンストラクターを 1 つだけ持つことで、名前が常に設定されていることを確認する方がよいのではないかと思います。

class Tool
{
public:
  //Constructor already does the right thing
  Tool() = default;
  virtual ~Tool();

  //Use void or return the modified class, akin to operators
  void setName(const std::string& name)
  {
    m_name = name;
  }
  //Alternatively
  Tool& setName(const std::string &name)
  {
    m_name = name;
    return *this;
  }

  //Return const reference to the value if possible, avoids copying if not needed
  //This will fail at run time if name is not set
  //Maybe throw an exception if that is preferred
  const std::string& getName() const
  {
    return *m_name;

    //Or

    if(m_name) return *m_name;
    else throw some_exception;
  }

  //Or return the optional, then calling code can check if name where set or not
  const boost::optional<std::string>& getName() const
  {
    return m_name;
  }


  void clearName()
  {
    m_name = boost::optional<std::string>();
  }

private:
  boost::optional<std::string> m_name;
};
于 2013-03-05T12:56:54.120 に答える
0

私はそれをパラダイムとは呼びません。これは、フィールドが指定されていない状態にある可能性があるアーキテクチャのソリューションのようです (そうでないのはなぜですか? 時にはそれが正気の要件である場合もあります)。ただし、getter は値を返すことになっているため (対称的に、setter はそれを設定することになっています)、慣例では通常、特定のプロトタイプが必要になるため、このソリューションはあまり好きではありません。

Type GetValue();
SetValue (const Type & newValue);
or
SetValue (Type & newValue);
or
SetValue (Type newValue);

状況に応じて 3 つのセッターのいずれかを選択する必要があり、通常は 1 番目または 2 番目のセッターが適しています。

フィールドが不特定の状態にある可能性がある場合は、M M. が彼の回答で示唆しているように、別のアプローチを選択します。自由に例を挙げます。

class C
{
private:
    int field;
    bool fieldSet;

public:
    C()
    {
        field = 0;
        fieldSet = false;
    }

    bool IsFieldSet()
    {
        return fieldSet;
    }

    int GetField()
    {
        if (!fieldSet)
            throw std::exception("Attempt to use unset field!");

        return field;
    }

    void SetField(const int newValue)
    {
        field = newValue;
        fieldSet = true;
    }
};

ただし、ゲッターを実装するこの方法をとは呼ばないことに注意してください。使いにくいだけかもしれません。

于 2013-03-05T12:38:44.997 に答える