为成员对象的方法别名的最佳方法? “直通方法”
考虑以下代码:
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;
...但不幸的是,这两种方法似乎都不起作用,而且这首先只是一厢情愿的想法。如果没有更简单的选择,告诉我也可以。谢谢!
Consider the following code:
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;
};
This code works fine.
My question deals with the "passthrough" functions in the House class, enclosed by the PASSTHROUGHS tags. Is this the best way to do this? The arguments and return types will always match and there is no "intelligence" in these passthrough functions other than to make things cleaner and more straightforward.
My instinct would be something like one of the following:
get_b_name = _base.get_name;
// OR
std::string get_b_name(void) = _base.get_name;
... but neither seem to work unfortunately and it was only wishful thinking in the first place. If there are no easier options, telling me that is fine too. Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为问题是概念性的。你的设计完全是非面向对象的,因为房子并不代表一个实体,而是在组件周围提供了一些胶水。从这个角度来看,提供元素的访问器而不是传递函数更有意义:
我想这只是一个玩具示例,但同样的推理也适用:一个类应该表示一个实体,在该实体上有一组操作是执行的,在某些情况下,这些操作可能是根据内部子对象来实现的,但它们仍然是对类型的操作,并且如何收集它们是实现细节。
考虑:
从用户的角度来看,房子有一个可以读取的温度,在这个特定的实现中,它是从作为成员的恒温器读取的。但这是一个实现细节。您稍后可能希望在房屋中安装更多恒温器,并用读数的平均值替换单个读数,但这不会改变实体房屋(在此模型中)具有温度的事实。
也就是说,您不应该考虑实现传递函数,而应该考虑实现该类型的功能。如果实现恰好是对内部方法的单个转发,那很好。
但是,如果类型包含内部成员并且访问成员的属性是有意义的,请考虑您的实际类型可能只应提供对其内部成员的访问。考虑到您想要在房子内移动钢琴,那么您可能只提供对门构件的访问并让用户检查:
不需要提供
House::get_door_width()
,并且 < code>House::get_door_color() 以便您可以向朋友描述入口,House::get_door_handle()
以便他们知道何时到达...The problem, I think, is conceptual. Your design is quite un-object oriented in that the house does not represent an entity, but rather provides a bit of glue around the components. From that standpoint, it would make more sense to provide accessors to the elements, rather than pass-through functions:
I imagine that this is just a toy example, but the same reasoning applies: a class should represent an entity on which a set of operations are preformed, in some cases those operations might be implemented in terms of internal subobjects, but they are still operations on the type, and how they are gathered is an implementation detail.
Consider:
From the user point of view the house has a temperature that can be read, and in this particular implementation, it is read from a thermostat that is a member. But that is an implementation detail. You might want to later install more thermostats in the house and substitute the single reading by an average of the readings, but that will not change the fact that the entity House (in this model) has a temperature.
That is, you should not be thinking in implementing pass-through functions, but rather on implementing features of the type. If the implementation happens to be a single forwarding to an internal method, that is fine.
But if the type contains internal members and it makes sense to access properties of the members, consider that it might be that you actual type should just provide access to its internal members. Consider that you want to move a piano inside the house, then you might just provide access to the door member and let the user check:
There is no need to provide
House::get_door_width()
, andHouse::get_door_color()
so that you can describe the entrance to a friend, andHouse::get_door_handle()
so that they can know when they arrive...这可能是因为你的设计是矛盾的。为什么要创建一个公共成员变量,然后编写一个仅转发到该变量的函数之一的函数?作为您班级的用户,我只需自己调用公共变量上的函数。你只是通过提供两种方法来做同样的事情让我感到困惑。或者为 Rectangle 类编写 getter 和 setter?那东西只是一堆变量,不需要任何 getter 和 setter。你并不完全要继承它,你也不能真正改变内部逻辑并保持相同的语义,所以不只是将变量公开是非常没有意义的。
矩形类需要非常健康剂量的 YAGNI ,而 House 类只需要再审视一下自己。 “直通”方法中没有智能的事实应该是一个巨大的警钟,告诉您它们很可能是多余的并且没有帮助 - 特别是因为无论如何您都无法在不破坏界面的情况下更改公共变量,这不像getter 和 setter 正在减少耦合或类似的东西。
方法应该执行逻辑,或者在最起码的情况下,存在于可能必须执行逻辑的地方。
That's possibly because your design is contradictory. Why on earth would you make a public member variable, then write a function that just forwards to one of that variable's functions? As a user of your class, I'd just call the function on the public variable myself. You're just confusing me by providing two ways to do the same thing. Or write getters and setters for a Rectangle class? That thing is just a bunch of variables, and doesn't need any getters and setters. You're not exactly going to inherit from it, and you can't really change the internal logic and maintain the same semantics, so it's very meaningless to not just make the variables public.
The Rectangle class needs a very healthy dose of YAGNI, and the House class just needs to look at itself again. The fact that there's no intelligence in the "passthrough" methods should be a huge alarm bell telling you that they are quite probably redundant and not helpful- especially since you can't change the public variables without breaking your interface anyway, it's not like the getters and setters are decreasing coupling or anything like that.
Methods should perform logic, or in the very least case, exist where logic might have to be done.