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

时间:2012-03-22 19:04:31

标签: c++ function private-methods

这是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进行操作,我真的把它分成两个函数来使代码更具可读性。

是的,这更像是一个讨论问题,而不是一个“回答”问题,但我对这个推理更感兴趣。我会将答案标记为答案,提供良好的推理或良好的标准。

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

5 个答案:

答案 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_Member1A的固有部分。
  • 即可。做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的地址,这是一个额外的副本到堆栈上。