7

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

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

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

4

5 回答 5

3

既然您要征求意见,那么如果独立f(CMyClass&)功能有意义并且可以实现,那么我也赞成该选项。我会选择第一种情况,如果由 执行的操作f仅在 A 类的上下文中有意义,如果CMyClass仅在 A 的上下文中有意义,或者它取决于A. 我认为必须根据问题做出决定。

于 2012-03-22T19:19:22.057 回答
2

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

在您给出的具体示例中 - 首先我会排除您的替代方案 ( void A::f(CMyClass &x)),主要是因为它“闻起来”很糟糕(正如 Martin Fowler 所说)。这是一个私有函数,除非你现在需要将它用于其他实例,否则让它使用成员。如果需要,您可以随时重构它。

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

如果f必须将其中一些参数发送到其他方法A怎么办?为此使用成员不是更有意义吗?

所有这一切都假设f确实需要其他信息A,否则我会将其移动为CMyClass.

于 2012-03-22T19:27:11.393 回答
1

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

于 2012-03-22T19:25:20.933 回答
1

f在第二个示例中,作为 的静态函数A或全局函数,或者可能是 的成员函数,难道不是更好CMyClass吗?

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

此外,正如Clean Code所述,您最好使用不带任何参数的函数,而不是使用带参数的函数。当另一个程序员试图读取函数时,除了函数名之外,它必须破译/注意第二个参数。

于 2012-03-22T19:24:11.480 回答
1

f()问问自己:用 以外的对象调用它现在是否有意义,或者在可预见的将来是否有任何意义m_Member1

如果答案是:

  • 没有。做一个无参数f()的,因为m_Member1它是A.
  • 的。做f(CMyClass &). 即使现在您只使用m_Member1,这也不是您处理的类的内在属性。
  • 也许。好吧...我会说使用无参数f()。总是可以选择改变你的想法(实际上,这种改变相当微不足道)。

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

于 2012-03-22T19:19:01.433 回答