成员对象的别名方法的最佳方法? “Passthrough方法”

时间:2011-06-02 18:23:59

标签: c++ function alias

请考虑以下代码:

class Rectangle
{
public:
    // Constructors
    Rectangle(){ init(0,0); }
    Rectangle(int h, int w){ init(h,w); }

    // Methods
    void init(int h, int w)
    {
        _h = h;
        _w = w;
    }

    // Getters / Setters
    double get_h(void){ return _h; }
    double get_w(void){ return _w; }
    void set_h(double h){ _h = h;  }
    void set_w(double w){ _w = w;  }
    std::string get_name(void){ return _name; }
    void set_name(std::string name){ _name = name; }

private:
    // Private Members
    int _h, _w;
    std::string _name;
};

class House
{
public: 
    // <BEGIN PASSTHROUGHS>
    std::string get_b_name(void){ return _base.get_name() };
    std::string get_r_name(void){ return _roof.get_name() };
    void set_b_name(std::string name){ _base.set_name(name); }
    void set_r_name(std::string name){ _roof.set_name(name); }
    // </END PASSTHROUGHS>

private:
    // Private Members
    Rectangle _base;
    Triangle  _roof;
};

此代码工作正常。

我的问题涉及House类中的“passthrough”函数,由PASSTHROUGHS标记括起来。这是最好的方法吗?参数和返回类型将始终匹配,除了使事情更清晰,更直接之外,这些直通函数中没有“智能”。

我的直觉类似于以下之一:

get_b_name = _base.get_name;

// OR

std::string get_b_name(void) = _base.get_name;

......但不幸的是,它们似乎都不起作用,这只是一开始只是一厢情愿的想法。如果没有更简单的选择,告诉我这也没关系。谢谢!

2 个答案:

答案 0 :(得分:4)

我认为这个问题是概念性的。你的设计是非面向对象的,因为房子不代表实体,而是在组件周围提供一些胶水。从这个角度来看,为元素提供访问器更有意义,而不是传递函数:

class House {
   Rectangle _base;
   Triangle  _roof;
public:
   const Rectangle& base() const {
      return _base;
   }
   const Triangle& roof() const {
      return _roof;
   }
};

我想这只是一个玩具示例,但同样的推理也适用:一个类应该代表一个实体,在该实体上执行一组操作,在某些情况下,这些操作可能是根据内部子对象实现的,但它们是仍然是对类型的操作,以及如何收集它们是一个实现细节。

考虑:

class House {
   Thermostat t;
public:
   int temperature() const {
      return t.temperature();
   }
};

从用户的角度来看,房屋具有可以读取的温度,并且在该特定实施方式中,房屋是从作为成员的恒温器读取的。但这是一个实现细节。您可能希望稍后在房屋中安装更多的恒温器并用平均读数替换单个读数,但这不会改变实体House(在此模型中)具有温度的事实。

也就是说,您不应该考虑实现传递函数,而应该考虑实现该类型的功能。如果实现恰好是单个转发到内部方法,那很好。

但是如果类型包含内部成员并且访问成员的属性是有意义的,请考虑可能是您的实际类型应该只提供对其内部成员的访问权限。考虑一下你想在房子内移动钢琴,然后你可能只是提供对门成员的访问并让用户检查:

class House {
   Door d;
public:
   Door const & door() const {
      return d;
   }
};
bool can_enter_piano( House const & h, Piano const & p ) {
   return h.door().width() > p.size();
}

无需提供House::get_door_width()House::get_door_color(),以便您可以描述朋友的入口和House::get_door_handle(),以便他们知道何时到达...... < / p>

答案 1 :(得分:-2)

这可能是因为你的设计是矛盾的。为什么你要创建一个公共成员变量,然后编写一个只转发给该变量函数之一的函数?作为班级的用户,我只是自己调用公共变量上的函数。你只是提供两种方法来做同样的事情,这让我很困惑。或者为Rectangle类编写getter和setter?那东西只是一堆变量,不需要任何getter和setter。你不会完全继承它,你不能真正改变内部逻辑并保持相同的语义,所以不仅仅是公开变量也没有意义。

Rectangle类需要一个非常健康的剂量YAGNI,House类只需要再看一遍。 “passthrough”方法中没有智能的事实应该是一个巨大的警钟,告诉你它们很可能是多余的而且没有帮助 - 特别是因为你不能在不破坏你的界面的情况下改变公共变量,它不像吸气剂和制定者正在减少耦合或类似的东西。

方法应该执行逻辑,或者至少存在逻辑可能的地方。