C ++将源文件内部的某些功能设为私有的最佳方法是什么?

问题描述

// 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应该是实现细节,请考虑仅在翻译单元中声明它。为此,您有两个常用选项。

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

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

    通过这种方式,您可以从privateFunction()调用publicFunction,同时仍然可以防止在编译单元外部使用privateFunction

  2. 在翻译单元中使用功能static

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

    与1具有相同的作用。

在1.和2.之间进行选择主要取决于品味。如果您希望对函数定义进行排序,以使被调用函数出现在调用函数的下方,请选择2.,因为1.在声明时强制执行函数定义。

请注意,这种隔离的缺点是无法为辅助功能编写特定的单元测试,因为您无法与“外部”的功能进行链接。

,

解决方案1 ​​

声明函数static

static void privateFunction() { ... }

解决方案2

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

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

在这两种情况下,该函数均具有内部链接,这意味着它仅在翻译单元中可见。

,

另一种方法是使用类,并且可以在类内部使用“私有”和“公共”来分隔函数和变量。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...