【问题标题】:Where to put helper functions pertaining to class method in C++C++中与类方法有关的辅助函数放在哪里
【发布时间】:2020-04-06 16:30:30
【问题描述】:

假设我有这样的课程Foo

foo.h

namespace mine {

class Foo {
  Widget widget_;
public:
  void bar();
  // some other members...
};

} // namespace mine

foo.cpp

#include "foo.h"
namespace mine {

void Foo::bar() {
  // Some very long code
}

} // namespace mine

出于可读性原因,我想将bar() 拆分为多个函数。函数本身对Foo(或除Foo::bar() 之外的任何其他实体)没有任何特殊意义,仅用于拆分bar(),因此根据this 讨论,我将在源代码中执行以下操作文件:

foo.cpp(重构):

#include "foo.h"

// anonymous namespace to put all helper functions
namespace {

void computeResult() { ... }
void modifyWidget(Widget& w) { ... }
void doThis() { ... }
void doThat(Widget& w) { 
  // ... 
  modifyWidget(w);
}

} // <anonymous> namespace

// actual methods are defined here    
namespace mine {

void Foo::bar() {
  ::doThis();
  ::doThat(widget_);
  ::computeResult();
}

} // namespace mine

所以我在源文件中定义了一个匿名命名空间以定义辅助函数,这样我就有了静态链接并且辅助函数从源文件外部不可见。让我觉得奇怪的一件事是,类方法依赖于不属于类的函数,但如果这是一个问题,我们甚至无法使用标准库。

  • 这种方法合理吗?你有更好的建议吗?
  • 将私有成员Foo::widget_ 传递给修改它的某个独立函数(doThat()) 是否有问题?我在这里假设在静态链接辅助函数的狭窄上下文中,调用者/被调用者知道他们在做什么。

【问题讨论】:

  • 正如您的命名所暗示的,我猜它与(GUI)小部件有关?我知道在初始化窗口或其他东西时 Qt 有同样的问题,你有很多代码连接按钮、设置标签、计算开始值以放入 textedits 等。我想这也是这种情况?
  • @RoQuOTriX 这更像是一个metasyntactic variable 名称,与任何特定的代码段无关:-)

标签: c++ function namespaces class-design linkage


【解决方案1】:
  1. 是的,这是明智的。这也并不少见,我的印象是它越来越受欢迎。
  2. 链接对函数的工作方式没有任何影响,并且私有成员变量的工作方式与所有其他变量完全相同(除了您无法从外部访问其名称)。
    也就是说,它就像将任何变量传递给任何函数一样。

【讨论】:

  • 感谢您的宝贵回答。我的第二点的意思是,由于辅助函数只能在同一个 TU 中访问,所以它们看起来很奇怪或接受时髦的参数应该是可以的。毕竟,它们只是辅助函数。