简体   繁体   English

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

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

Here's a question that comes up again and again in C++ class implementation. 这是C ++类实现中一次又一次出现的问题。 I'm curious about what people's thoughts are here. 我很好奇人们的想法在这里。 Which code do you prefer and why? 您更喜欢哪种代码?为什么?

class A
{
public:
    /* Constructors, Destructors, Public interface functions, etc. */ 
    void publicCall(void);

private:
    void f(void);

    CMyClass m_Member1;
};

with

void A::publicCall(void)
{
    f();
}

void A::f(void)
{
    // do some stuff populating  m_Member1
}

Or the alternative: 或替代方案:

class A
{
public:
    /* Constructors, Destructors, Public interface functions, etc. */ 
    void publicCall(void);

private:
    void f(CMyClass &x);

    CMyClass m_Member1;
};

with

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
}

I think I always prefer the second one because then f can then operate on any instance of CMyClass but, that said, I have lots of code where the first is perfectly valid since f will only ever operate on m_Member1 and I'm really breaking it into two functions to make the code more readable. 我想我总是更喜欢第二个,因为然后f可以在CMyClass任何实例上运行,但是,说,我有很多代码,其中第一个完全有效,因为f只会在m_Member1m_Member1而我真的打破了它分为两个函数,使代码更具可读性。

Yes, this is more of a discussion question than an "answer" question, but I'm more interested in the reasoning. 是的,这更像是一个讨论问题,而不是一个“答案”问题,但我对这个推理更感兴趣。 I'll mark as an answer a response that gives good reasoning or a good criterion. 我会将答案标记为答案,提供良好的推理或良好的标准。

Also, keep in mind that this is just a toy example. 另外,请记住,这只是一个玩具示例。 The class will be bigger than this in reality and thus organization is important. 在现实中,这个班级将比这更大,因此组织很重要。

Since you're asking for opinions, if a standalone f(CMyClass&) function makes sense and is implementable, then I would also favour that option. 既然你要求意见,如果一个独立的f(CMyClass&)函数有意义且可实现,那么我也赞成这个选项。 I would opt for the first case if the operation performed by f only makes sense in the context of class A, if CMyClass only makes sense in A's context, or if it depends on other attributes of A . 我会选择第一种情况,如果f执行的操作仅在A类的上下文中有意义,如果CMyClass仅在A的上下文中有意义,或者它依赖于A其他属性。 I think one has have to decide depending on the problem. 我认为必须根据问题做出决定。

As always, that depends. 一如既往,这取决于。 Each scenario is different. 每种情况都不同。

In the specific example you gave - first I'd rule out your alternative ( void A::f(CMyClass &x) ) mainly because it 'smells' bad (as Martin Fowler puts it). 在你给出的具体例子中 - 首先我排除了你的选择( void A::f(CMyClass &x) ),主要是因为它“闻起来”不好(正如Martin Fowler所说)。 It's a private function, and unless you need to use it now for other instances, make it use the member. 它是一个私有函数,除非您现在需要将其用于其他实例,否则请使用该成员。 You can always refactor it if the need arises. 如果需要,您可以随时重构它。

Imagine what would happen if f had 2 parameters. 想象一下如果f有2个参数会发生什么。 3 parameters. 3个参数。 10. Would it make sense then to send them each time? 10.每次发送它们是否有意义? Wouldn't it be better to have these parameters members? 拥有这些参数成员不是更好吗?

And what if f had to send some of these arguments to other methods of A ? 如果f必须将其中一些参数发送给A其他方法怎么办? Doesn't it make more sense to use members for this? 使用成员为此更有意义吗?

All of this is assuming that f does need other information which A holds, otherwise I'd move it to be a method of CMyClass . 所有这一切都假设f确实需要A持有的其他信息,否则我将其移动为CMyClass的方法。

Ask yourself: Does it have any meaning now, or may it have any meaning in the foreseable future, to call f() with an object other than m_Member1 ? 问问自己:用m_Member1以外的对象调用f() ,它现在有什么意义,或者在可预见的将来是否有任何意义?

If the answer is: 如果答案是:

  • No . Do a parameterless f() as m_Member1 is an intrinsic part of A . 无参数f()m_Member1A的固有部分。
  • Yes . 是的 Do the f(CMyClass &) . f(CMyClass &) Even if now you only use m_Member1 , that is not an intrinsic property of the classes you handle. 即使现在你只使用m_Member1 ,这也不是你处理的类的内在属性。
  • Maybe . 也许吧 Well... I'd say go with the parameterless f() . 好吧......我会说参数无参数f() There is always the option to change your mind (the change if fairly trivial, actually). 总有一种选择可以改变你的想法(实际上,如果变化相当微不足道)。

Also note that a function f() can call another function g(CMyClass &) , but not the other way around. 另请注意,函数f()可以调用另一个函数g(CMyClass &) ,但不能相反。 So, depending on what f() does, that may limit your options. 因此,根据f()作用,这可能会限制您的选择。

Isn't f in the second example better of as a static function of A or global function or, maybe, a member function of CMyClass ? 第二个例子中的f不是A或全局函数的静态函数,或者是CMyClass的成员函数吗?

Of course, there are cases where you're better off sending the argument every time you call that function, but why would you resend it when you already have on CMyClass object in the A object. 当然,有些情况下,每次调用该函数时最好发送参数,但是当你已经拥有A对象中的CMyClass对象时,为什么还要重新发送它。 If you need both CMyClass objects to interact, you may be better off adding it to CMyClass member function list, rather than to A . 如果您需要两个CMyClass对象进行交互,最好将其添加到CMyClass成员函数列表中,而不是添加到A

Also, as Clean Code states, you're better off with functions without any arguments, than with ones with arguments. 此外,正如清洁代码所述,你最好使用没有任何参数的函数,而不是带有参数的函数。 When another programmer tries to read the function, it must decipher/pay attention to the second parameter, besides the function name. 当另一个程序员试图读取该函数时,除了函数名之外,它必须解密/注意第二个参数。

I would base the answer on the context. 我的答案将基于背景。 If there are now or might some day be multiple instances of member variables that f might operate on, then sure, pass it/them as parameters. 如果现在或某天可能有多个成员变量实例可能会运行,那么请确保将它们作为参数传递给它们。 However, if f is operating on specific elements of the state of the instance of A, I would not pass anything to it. 但是,如果f对A实例的状态的特定元素进行操作,我不会传递任何内容。 There are lots of cases where there will always be only one foo in an A. At that point is becomes silly to make foo a parameter to f. 在很多情况下,A中总会只有一个foo。在这一点上,使foo成为f的参数变得愚蠢。 And slightly less efficient, unless f is inline, since not only is the this pointer being passed, but also the address of foo, which is an extra copy onto the stack. 并且效率稍差,除非f是内联的,因为不仅是这个指针被传递,而且还有foo的地址,这是一个额外的副本到堆栈上。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM