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

2023-12-22

// 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() from publicFunction,仍然保护任何使用privateFunction来自编译单元外部。

  2. 使函数static在翻译单元内。

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

    与1具有相同的效果。

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ 将源文件中的某些函数设为私有的最佳方法是什么? 的相关文章

  • 如何在C++中生成非常大的随机数

    我想使用 C 生成 0 2 64 范围内的非常大的随机数 我已经使用了 rand 函数 但它没有生成非常大的数字 有人可以帮忙吗 使用c 11 使用标准c 11的随机库 http en cppreference com w cpp nume
  • 什么定义了类型的大小?

    ISO C 标准规定 sizeof char lt sizeof short lt sizeof int lt sizeof long 我在 BIT Linux mint 19 1 上使用 GCC 8 大小为long int is 8 我正
  • 如何使用 Entity Framework 和 Identity 解决对象处置异常 ASP.NET Core

    我正在尝试编写一个控制器 该控制器接收来自 AJAX 调用的请求并通过 DBContext 对数据库执行一些调用 但是 当我发出命令时var user await GetCurrentUserAsynch 在对 DBContext 的任何调
  • getline 之后返回到文件开头

    所以我已经从文件中读取了所有行 while getline ifile line logic 其中 ifile 是 ifstream line 是字符串 我的问题是我现在想再次使用 getline 并且似乎无法返回到文件的开头 因为运行 c
  • 更新 Azure Blob 上的 LastModified

    我正在移植代码以使用 C 中的 Azure 存储 SDK 传统上 我称其为更新修改文件的上次写入 修改时间 File SetLastWriteTimeUtc fileName lastWriteTimeUtc 要更新 blob 的上次修改时
  • C# 异步任务比同步慢

    你知道为什么同步斐波那契方法比异步 等待更快并且比异步任务更快吗 我在每个项目方法上都使用了异步 所以主要是这是一个非常糟糕的方法 Code static int FibonacciSync int number if number 0 r
  • 对 ExecuteNonQuery() 的单次调用是原子的

    对 ExecuteNonQuery 的单次调用是否是原子的 或者如果单个 DbCommand 中有多个 sql 语句 那么使用事务是否有意义 请参阅我的示例以进行说明 using var ts new TransactionScope us
  • C++ 指针和对象实例化

    这有效 MyObject o o new MyObject 而这并不 MyObject o new MyObject Why 关键词new 返回一个指针 http msdn microsoft com en us library kewsb
  • FluentAssertions ShouldNotThrow 无法识别异步方法/Func

    我正在尝试检查异步方法是否抛出具体异常 为此 我使用 MSTEST 和 FluentAssertions 2 0 1 我已经检查过这个关于 Codeplex 的讨论 http fluentassertions codeplex com wo
  • asp.net core http 如果没有内容类型标头,则删除 `FromBody` 忽略

    我在 http 中使用 bodyDELETE要求 我知道目前删除主体是非标准的 但是允许的 使用时出现问题HttpClient它不允许删除请求的正文 我知道我可以使用SendAsync 但我宁愿让我的 API 更加灵活 我希望这个机构是可选
  • 如何在 C++ 运行时更改 QML 对象的属性?

    我想在运行时更改 QML 对象的文本 我尝试如下 但文本仍然为空 这是后端类 class BackEnd public QObject Q OBJECT Q PROPERTY QString userFieldText READ userF
  • linq where 子句和 count 导致 null 异常

    除非 p School SchoolName 结果为 null 否则下面的代码将起作用 在这种情况下 它会导致 NullReferenceException if ExistingUsers Where p gt p StudentID i
  • Windows 上本机 C++ 应用程序中的自动死代码检测?

    背景 我有一个用原生 C 编写的应用程序 花了几年的时间 大约有 60 KLOC 有很多函数和类已经死了 可能有 10 15 就像下面提出的类似的基于 Unix 的问题 我们最近开始对所有新代码进行单元测试 并尽可能将其应用于修改后的代码
  • 如何禁用基于 ValidationRule 类的按钮?

    如何禁用基于 ValidationRule 类的 WPF 按钮 下面的代码可以很好地突出显示 TextBox
  • 应在堆栈上分配的最大数量

    我一直在寻找堆栈溢出有关应在堆栈上分配的最大内存量的指南 我看到了堆栈与堆分配的最佳实践 但没有关于应该在堆栈上分配多少以及应该在堆上分配多少的指南 有什么想法 数字可以作为指导吗 什么时候应该在堆栈上分配 什么时候应该在堆上分配 多少才算
  • 意外的 const 引用行为

    include
  • 如何释放字符串未使用的容量

    我正在程序中处理很多字符串 这些字符串数据在读入我的程序后的整个生命周期内都不会改变 但由于 C 字符串保留了容量 因此浪费了大量肯定不会被使用的空间 我尝试释放这些空间 但没有成功 以下是我尝试过的简单代码 string temp 123
  • 如何通过代理将套接字连接到http服务器?

    最近 我使用 C 语言编写了一个程序 用于连接到本地运行的 HTTP 服务器 从而向该服务器发出请求 这对我来说效果很好 之后 我尝试使用相同的代码连接到网络上的另一台服务器 例如 www google com 但我无法连接并从网络中的代理
  • C# PasswordDeriveBytes:似乎 Salt 并不重要

    可能我误解了什么 以下代码通过 CryptDeriveKey 使用两种不同的盐生成两个相等的密钥 这是控制台结果 盐1 21 3e 18 a3 9a 8b 5f gt 键 da 89 ea 3d 91 08 20 98 20 e9 dc 4
  • 强制函数调用的顺序?

    假设我有一个抽象基类 并且我想要一个必须由派生类实现的纯虚方法 但我想确保派生方法以特定顺序调用函数 我可以做什么来强制执行它 I E base class virtual void doABC 0 virtual void A 0 vir

随机推荐