C++ 什么是使源文件中的某些函数私有的最佳方法?

C++ what's the best way to make some functions inside source file private?

// myclass.h
#pragma once
void publicFunction();

//------
// myclass.cpp
#include "myclass.h"
#include <iostream>

void privateFunction() {
    std::cout << "Hello world\n";
}

void publicFunction() {
    privateFunction();
}

//-------
// main.cpp
#include "myclass.h"
#include <iostream>

void privateFunction() {
    std::cout << "Hello main\n";
}

int main()
{
    privateFunction();
}

以上程序将无法编译(privateFunction(void) already defined in myclass.obj)。解决这个问题的一种方法是在源文件中定义一个 namespace

#include "myclass.h"
#include <iostream>

namespace MyClass
{
    void privateFunction();
    // add a bunch other private functions here
}

void MyClass::privateFunction() {
    std::cout << "Hello world\n";
}
//---
using namespace MyClass;

void publicFunction() {
    privateFunction();
}

这是解决这个问题的正确方法吗?感觉这样以后可能会出现一些问题,但是不知道怎样做才是正确的。

解决方案 1:

声明函数static

static void privateFunction() { ... }

解决方案 2:

在未命名的命名空间中声明函数。

namespace {
    void privateFunction() { ... }
}

在这两种情况下,函数都获得 内部链接,这意味着它仅在翻译单元内可见。

另一种方法是使用 class,在 class 中,您可以使用“private”和“public”来分隔函数和变量。

如果您在头文件中声明了一个函数,那么 private 开头就不是了。如果 privateFunction 应该是一个实现细节,请考虑仅在翻译单元中声明它。为此,您有两个常见的选择。

  1. 在实现文件中使用匿名namespace

    namespace {
      void privateFunction() {
        std::cout << "Hello world\n";
      }
    }
    

    通过这种方式,您可以从 publicFunction 调用 privateFunction(),仍然保护编译单元外部对 privateFunction 的任何使用。

  2. 在翻译单元内创建函数static

    static void privateFunction() {
        std::cout << "Hello world\n";
    }
    

    与1效果相同

在 1. 和 2. 之间做出选择主要是个人喜好问题。如果您想对函数定义进行排序,使被调用函数出现在调用函数下方,请选择 2.,因为 1. 在声明点强制执行函数定义。

请注意,这种隔离的缺点是降低了为辅助函数编写特定单元测试的能力,因为您无法 link 对抗来自“外部”的测试。