【问题标题】:C++ - Getting and setting member variable within same method?C++ - 在同一方法中获取和设置成员变量?
【发布时间】:2014-11-29 17:21:26
【问题描述】:

我有一个派生自包含其自己的成员变量的基类的类。为了将类中的所有内容都封装起来,我试图找出一种干净的方法来设置此成员变量,同时以相同的方法检索它。这是该方法的样子(这是伪代码,可能无法编译):

class Base
{
    virtual void MyVirtualMethod(double &output1, Object &output2)
    {
        // do base class stuff (does not set output1 because it does not need to)...
        output2 = whatever;
    }
}

class Derived
{
public:
    virtual void MyVirtualMethod(double &output1, Object &output2)
    {
        // do derived class stuff...

        m_DerivedMember = whatever;

        // do more stuff...

        output1 = m_DerivedMember;
        output2 = whatever2;
    }

private:
    double m_DerivedMember;
}

调用代码#1

std::vector<DataPack> dataPack;

for each Base pointer...
{
    double output1(100); // some default value
    Object output2;
    base->MyVirtualMethod(output1, output2);

    dataPack.push_back(DataPack(output1, output2));
}

调用代码#2

double output1(100); // some default value
Object output2;
base->MyVirtualMethod(output1, output2);

// do more stuff but does not actually use output1, just output2...

虽然这可行,但对我来说似乎并不干净。我想我问自己的更大问题是同时使用与 getter 和 setter 相同的方法是否是个好主意?谢谢!

【问题讨论】:

  • “我想我要问自己的更大的问题是,使用与 getter 和 setter 相同的方法是否是个好主意……”您的示例中没有任何 getter/setter 函数?
  • 我的意思是在同一方法中设置和获取成员变量是否是个好主意。它没有标记为 Get 或 Set 方法,而是在它设置和获取该成员变量的方法内部。
  • 这就是所谓的状态操作(与getter/setter无关)。如果不允许这样,OOP 的整个概念将毫无用处。
  • 在 C++ 中,“getter”和“setter”通常被称为 mutatorsaccessors。我认为从 mutator 返回值没有错。
  • 谢谢大家!我想出了一种不同的方法来清理它,但它基本上涉及将设置器部分移动到其他地方。这是一个额外的函数调用,但不是世界末日,因为这项工作不是在关键线程上完成的。

标签: c++ virtual setter getter


【解决方案1】:

虽然我不建议这样做,但您可以返回对您的成员的引用,这将允许您进行 get/set 操作。这就是std::vector 通过重载operator[] 工作的方式。比如:

#include <iostream>
using namespace std;

class Foo
{
  int m_;
public:
  Foo(int m): m_(m){}
  int& get_set()
  {
     return m_;
  } 
  const int& get_set() const // for const-access
  {
     return m_;
  }
}; 

int main()
{
  Foo foo(10);
  cout << foo.get_set() << endl;
  foo.get_set() = 20;
  cout << foo.get_set() << endl;

  // that's why we need the `const` overload of `Foo::get_set`
  const Foo cfoo(100); 
  cout << cfoo.get_set() << endl;
}

【讨论】:

    【解决方案2】:

    为了回答您的问题,单独的 getter 和 setter 是封装的核心。虽然它可能会为您节省一个额外的函数调用,但使用单独的函数来获取和设置会更干净、更安全。这是一些经过调整的代码以便更好地理解

    class Derived : public Base
    {
    public:
        virtual void MyVirtualMethod(double &output1, Object &output2)
        {
            // do derived class stuff...
    
            m_DerivedMember = whatever;
    
            // do more stuff...
    
            output1 = m_DerivedMember;
            output2 = whatever2;
        }
    
    
    /*
    The setter
    */
    void setDerivedMember(double m){
        m_DerivedMember = m;
    }
    
    
    
    
    /* 
    the getter
    */
    
    double getDerivedMember(){
    
        return m_DerivedMember;
    }
    
    
    private:
        double m_DerivedMember;
    }
    

    我们可以像这样调用这些函数:

    Derived d(1.5, string("I'm a string"));
    d.setDerivedMember(5.00);
    cout <<"Derived Member Value: " d.getDerivedMember()<<endl;
    

    它会输出:

    Derived Member Value: 5.00
    

    希望这是有道理的!

    【讨论】:

      猜你喜欢
      • 2019-02-05
      • 1970-01-01
      • 2014-01-25
      • 1970-01-01
      • 1970-01-01
      • 2015-04-30
      • 1970-01-01
      • 2010-10-03
      • 2011-06-16
      相关资源
      最近更新 更多