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
应该是一个实现细节,请考虑仅在翻译单元中声明它。为此,您有两个常见的选择。
在实现文件中使用匿名namespace
。
namespace {
void privateFunction() {
std::cout << "Hello world\n";
}
}
通过这种方式,您可以从 publicFunction
调用 privateFunction()
,仍然保护编译单元外部对 privateFunction
的任何使用。
在翻译单元内创建函数static
。
static void privateFunction() {
std::cout << "Hello world\n";
}
与1效果相同
在 1. 和 2. 之间做出选择主要是个人喜好问题。如果您想对函数定义进行排序,使被调用函数出现在调用函数下方,请选择 2.,因为 1. 在声明点强制执行函数定义。
请注意,这种隔离的缺点是降低了为辅助函数编写特定单元测试的能力,因为您无法 link 对抗来自“外部”的测试。
// 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
应该是一个实现细节,请考虑仅在翻译单元中声明它。为此,您有两个常见的选择。
在实现文件中使用匿名
namespace
。namespace { void privateFunction() { std::cout << "Hello world\n"; } }
通过这种方式,您可以从
publicFunction
调用privateFunction()
,仍然保护编译单元外部对privateFunction
的任何使用。在翻译单元内创建函数
static
。static void privateFunction() { std::cout << "Hello world\n"; }
与1效果相同
在 1. 和 2. 之间做出选择主要是个人喜好问题。如果您想对函数定义进行排序,使被调用函数出现在调用函数下方,请选择 2.,因为 1. 在声明点强制执行函数定义。
请注意,这种隔离的缺点是降低了为辅助函数编写特定单元测试的能力,因为您无法 link 对抗来自“外部”的测试。