// 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();
}
这是解决此问题的正确方法吗?我觉得以后可能会引起一些问题,但是我不知道正确的方法是什么。

最佳答案

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

  • 在实现文件中使用匿名namespace
    namespace {
      void privateFunction() {
        std::cout << "Hello world\n";
      }
    }
    
    这样,您可以从privateFunction()调用publicFunction,仍然在编译单元外部保护privateFunction的任何使用。
  • 在翻译单元内制作函数static
    static void privateFunction() {
        std::cout << "Hello world\n";
    }
    
    与1具有相同的效果。

  • 在1.和2.之间进行选择主要取决于口味。如果您希望对函数定义进行排序,以使被调用函数出现在调用函数的下方,请选择2.,因为1.在声明的位置强制执行函数定义。
    请注意,这种隔离的缺点是为辅助功能编写特定的单元测试的能力降低,因为您无法与“外部”的链接。

    09-06 17:05