未命名命名空间中的自由函数与具有私有成员函数的类相比有什么好处?

问题描述 投票:0回答:3

与拥有不带任何参数的私有类成员函数并直接访问成员变量相比,拥有自由函数(在匿名命名空间中并且只能在单个源文件中访问)并将所有变量作为参数发送有什么优势?

标题:

 class A {
    int myVariable;
    void DoSomething() {
       myVariable = 1;
    }
 };

来源:

 namespace {
    void DoSomething2(int &a) {
        a = 1;
    }
 }

 int A::SomeFunction() {
    DoSomething2(myVariable); // calling free function
    DoSomething(); // calling member function
 }

如果您更喜欢将它们设为成员,那么如果我首先调用一个不访问任何成员变量的函数,但该函数调用另一个is访问成员的函数,该怎么办?它们都应该是会员功能还是免费的?

c++ dependencies member-functions pimpl-idiom non-member-functions
3个回答
28
投票

参见这个问题:Effective C++ Item 23 优先选择非成员非友元函数而不是成员函数 还有 C++ 成员函数与自由函数

您应该更喜欢自由函数,因为它可以促进松散耦合。

仅当它在你的类的内部有效,并且你认为它确实与你的类紧密相关时,才考虑将其设为成员函数。

这是101 C++ 编码标准一书中的一个观点,它指出比起成员函数更喜欢自由函数和静态函数。

虽然这可能被认为是基于意见的,但它允许保持课堂小,并分离关注点。

这个 answer 指出:“这条规则的原因是,通过使用成员函数,您可能会意外地过度依赖类的内部结构。”


14
投票

源文件中非成员函数的一个优点类似于Pimpl idiom的优点:如果您更改实现,使用您的标头的客户端不必重新编译。

// widget.h
class Widget 
{
public:
    void meh();
private:
    int bla_;
};

// widget.cpp
namespace {
    void helper(Widget* w) // clients will never know about this
    { /* yadayada */ }
}

void widget::meh() 
{ helper(this); }

当然,这样写的话,

helper()
只能使用
Widget
的公共接口,所以你收获甚微。您可以在
friend
内放置
helper()
Widget
声明,但在某些时候您最好切换到成熟的 Pimpl 解决方案。


8
投票

自由函数与成员函数相比的主要优点是它有助于将接口与实现解耦。例如,

std::sort
不需要知道关于它所操作的底层容器的任何事情,只需它被授予对提供某些特征的容器(通过迭代器)的访问权限即可。

在您的示例中,

DoSomething2
方法对于减少耦合没有多大作用,因为它仍然必须通过引用传递来访问私有成员。几乎可以肯定,在普通的
DoSomething
方法中进行状态突变会更明显。

当您可以根据类的公共接口实现任务或算法时,那么它就成为创建自由函数的良好候选者。 Scott Meyers 在这里总结了一套合理的规则:http://cpptips.com/nmemfunc_encap

© www.soinside.com 2019 - 2024. All rights reserved.