这是C ++类实现中一次又一次出现的问题。我很好奇人们的想法在这里。您更喜欢哪种代码?为什么?
class A
{
public:
/* Constructors, Destructors, Public interface functions, etc. */
void publicCall(void);
private:
void f(void);
CMyClass m_Member1;
};
与
void A::publicCall(void)
{
f();
}
void A::f(void)
{
// do some stuff populating m_Member1
}
或替代方案:
class A
{
public:
/* Constructors, Destructors, Public interface functions, etc. */
void publicCall(void);
private:
void f(CMyClass &x);
CMyClass m_Member1;
};
与
void A::publicCall(void)
{
f(m_Member1);
}
void A::f(CMyClass &x)
{
// do some stuff to populate x,
// locally masking the fact that it's really m_Member1
}
我认为我总是更喜欢第二个,因为f
然后可以对CMyClass
的任何实例进行操作,但是,我说有很多代码,其中第一个完全有效,因为{{1}只会对f
进行操作,我真的把它分成两个函数来使代码更具可读性。
是的,这更像是一个讨论问题,而不是一个“回答”问题,但我对这个推理更感兴趣。我会将答案标记为答案,提供良好的推理或良好的标准。
另外,请记住,这只是一个玩具示例。在现实中,这个班级将比这更大,因此组织很重要。
答案 0 :(得分:3)
既然你是在征求意见,如果一个独立的f(CMyClass&)
函数有意义并且可以实现,那么我也赞成这个选项。如果f
执行的操作仅在A类的上下文中有意义,如果CMyClass
仅在A的上下文中有意义,或者它依赖于{{的其他属性,那么我会选择第一种情况1}}。我认为必须根据问题做出决定。
答案 1 :(得分:2)
一如既往,这取决于。每种情况都不同。
在您给出的具体示例中 - 首先我排除了您的替代方案(void A::f(CMyClass &x)
),主要是因为它“闻起来”不好(正如Martin Fowler所说)。这是一个私有函数,除非您需要将 now 用于其他实例,否则请使用该成员。如果需要,你总是可以重构它。
想象一下如果f
有2个参数会发生什么。 3个参数。 10.每次发送它们是否有意义?拥有这些参数成员不是更好吗?
如果f
必须将其中一些参数发送到A
的其他方法,该怎么办?为此使用成员是否更有意义?
所有这一切都假设f
确实需要A
持有的其他信息,否则我会将其移至CMyClass
的方法。
答案 2 :(得分:1)
问问自己:现在有什么意义,或者在可预见的将来可能有任何意义,用f()
以外的对象来呼叫m_Member1
吗?
如果答案是:
f()
作为m_Member1
是A
的固有部分。f(CMyClass &)
。即使现在你只使用m_Member1
,这也不是你处理的类的固有属性。f()
。总有一种选择可以改变主意(实际上这种变化相当微不足道)。另请注意,函数f()
可以调用另一个函数g(CMyClass &)
,但不能相反。因此,根据f()
的作用,这可能会限制您的选择。
答案 3 :(得分:1)
第二个例子中的f
不是A
或全局函数的静态函数,或者是CMyClass
的成员函数吗?
当然,在某些情况下,每次调用该函数时最好发送参数,但是当你已经在A对象中使用CMyClass对象时,为什么要重新发送它?如果您需要两个CMyClass对象进行交互,最好将其添加到CMyClass
成员函数列表,而不是A
。
另外,正如Clean Code所述,你最好使用没有任何参数的函数,而不是带参数的函数。当另一个程序员试图读取该函数时,除了函数名之外,它必须解密/注意第二个参数。
答案 4 :(得分:1)
我的答案将基于背景。如果现在或某天可能有多个成员变量实例可能会运行,那么请确保将它们作为参数传递给它们。但是,如果f对A实例的状态的特定元素进行操作,我不会传递任何内容。在很多情况下,A中总会只有一个foo。在这一点上,使foo成为f的参数变得愚蠢。并且效率稍差,除非f是内联的,因为不仅是这个指针被传递,而且还有foo的地址,这是一个额外的副本到堆栈上。