C++私有函数:是否通过函数参数传递类成员变量
C++ Private Functions: Whether to pass class member variable by function parameter, or not
这里有一个问题在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_Member1
是A
的内在部分 -
是。执行
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的地址,这是堆栈上的额外副本。
- 如何在C++中将迭代器作为函数参数传递
- 为什么我不能将引用作为 std::async 的函数参数传递
- 节点插件 API 将数组作为函数参数传递
- 将字符串数组作为函数参数传递
- 如何通过 C++ 中的函数参数传递初始值设定项列表的固定大小的初始值设定项列表?
- 我可以动态创建新地图并作为函数参数传递吗?
- 将任意模板向量作为函数参数C++传递
- 将函数指针作为函数参数传递的目的
- C++:通过函数参数传递的值给出不同的结果
- 当数组大小在C++中未知时,如何在运行时将对字符串数组的引用作为函数参数传递?
- 通过宏将函数参数传递给函数
- C++:访问作为函数参数传递的双指针数组所指向的变量的值
- 如何将 std::string 作为构造函数参数传递,并将其保存的 C 字符串存储在 void 指针中?
- 将派生类构造函数参数传递给受保护的成员
- 将指向数组的指针作为函数参数传递,这本身就是另一个函数的返回值?
- 如何将二维数组类型字符(字符串)作为函数参数传递?
- 有什么理由C++ 11+ std::mutex 应该声明为全局变量,而不是作为函数参数传递到 std::thread 中
- 如何将派生类作为函数参数传递:如果派生类成员不在父类中怎么办
- 如何将变量作为构造函数参数或函数参数传递
- 当数组对象以函数参数传递时,为什么复制构造函数会自称