C++私有函数:是否通过函数参数传递类成员变量

C++ Private Functions: Whether to pass class member variable by function parameter, or not

本文关键字:函数 参数传递 成员 变量 是否 C++      更新时间:2023-10-16

这里有一个问题在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的任何实例进行操作,但也就是说,我有很多代码,其中第一个是完全有效的,因为f只会对m_Member1进行操作,我真的把它分成两个函数,以使代码更可读。

是的,这更像是一个讨论问题,而不是一个"答案"问题,但我对推理更感兴趣。我会把一个给出良好推理或良好标准的回答标记为答案。

此外,请记住,这只是一个玩具示例。在现实中,班级将比这更大,因此组织很重要。

由于您正在征求意见,如果一个独立的f(CMyClass&)函数是有意义的并且是可实现的,那么我也会支持该选项。如果f执行的操作仅在类A的上下文中有意义,如果CMyClass仅在A的上下文下有意义,或者如果它取决于A的其他属性,我会选择第一种情况。我认为必须根据问题做出决定。

一如既往,这取决于情况。每个场景都不同。

在你给出的具体例子中,首先我会排除你的替代品(void A::f(CMyClass &x)),主要是因为它"闻起来"很难闻(正如马丁·福勒所说)。它是一个私有函数,除非您现在需要在其他实例中使用它,否则请使用该成员。如果需要,您可以随时对其进行重构。

想象一下,如果f有两个参数会发生什么。3个参数。10.那么每次都发送它们有意义吗?拥有这些参数成员不是更好吗?

如果f必须将其中一些参数发送到A的其他方法,该怎么办?使用成员做这件事不是更有意义吗?

所有这些都假设f确实需要A保存的其他信息,否则我会将其移动为CMyClass的方法。

问问自己:用m_Member1以外的对象调用f()现在有意义吗,或者在可预见的未来有意义吗?

如果答案是:

  • 。做一个无参数的f(),因为m_Member1A的内在部分
  • 。执行f(CMyClass &)。即使现在只使用m_Member1,它也不是您处理的类的内在属性
  • 也许。好我建议使用无参数的f()。总有一种选择可以改变你的想法(事实上,这种改变虽然微不足道)

还要注意,函数f()可以调用另一个函数g(CMyClass &),但不能反过来调用。因此,根据f()的作用,这可能会限制您的选择。

第二个例子中的f不是更适合作为A的静态函数或全局函数,或者可能是CMyClass的成员函数吗?

当然,在某些情况下,最好每次调用该函数时都发送参数,但当A对象中已经有CMyClass对象时,为什么要重新发送它呢。如果您需要两个CMyClass对象进行交互,那么最好将其添加到CMyClass成员函数列表中,而不是添加到A中。

此外,正如Clean Code所说,使用没有任何参数的函数比使用有参数的函数要好。当另一个程序员试图读取函数时,除了函数名之外,还必须解密/注意第二个参数。

我会根据上下文给出答案。如果现在或将来可能有多个成员变量实例可以由f操作,那么一定要将其作为参数传递。然而,如果f对A实例的状态的特定元素进行操作,我不会向它传递任何信息。在很多情况下,A中总是只有一个foo。在这一点上,将foo作为f的参数变得很愚蠢。而且效率稍低,除非f是内联的,因为不仅传递this指针,还传递foo的地址,这是堆栈上的额外副本。