【问题标题】:Wrapping C++ functionalities from std, is sometimes a bad idea? [closed]从 std 包装 C++ 功能有时是个坏主意? [关闭]
【发布时间】:2013-10-29 15:11:29
【问题描述】:

我的问题是关于包装 std 库中的一些容器或对象,以及这样做的成本。 假设我需要创建一个 ThreadSafeStack 类。我将包装std::stack 容器并使用互斥锁使其线程安全。这完全没问题,因为新的ThreadSafeStack 的功能值得付出代价(函数调用)。但是,如果我想将std::mutex 包装到一个类MyMutex 中以在调试时添加日志功能怎么办?在您看来,值得还是不值得?

如果我这样做只是为了方便,以避免在我的所有文件中写入std::using::std 怎么办?你觉得这很愚蠢吗?

我读过一些关于函数调用的文章(例如this),我想说这不会是一个很大的开销。

【问题讨论】:

  • 您的包装函数调用很可能会在适当的优化级别内联,从而导致 ZERO 开销。例如检查this case:指针解引用包装到operator* 导致与原始指针解引用相同的汇编代码。许多级别的 C++ 抽象可以在优化过程中消失。
  • 我还要补充一点,如果您正在执行 IO(例如写入日志文件),那么函数调用是您最不关心的问题。
  • 你是对的@selalerer。
  • 感谢@Evgeny Panasyuk 的示例。我们可以将您的快速回答视为答案吗?
  • 这是decorator pattern,如果正确完成,我发现它非常有用。阅读它。

标签: c++


【解决方案1】:

这完全没问题,因为新的 ThreadSafeStack 的功能物有所值(函数调用)。

您的包装函数调用很可能会在适当的优化级别内联,从而导致零开销。例如检查this case:指针解引用包装到operator* 导致与原始指针解引用相同的汇编代码。许多级别的 C++ 抽象可以在优化过程中消失。

不过,虚函数调用不太可能被内联。因此,在有意义的情况下使用普通函数。

但是,如果我想将 std::mutex 包装到 MyMutex 类中以在调试时添加日志记录功能怎么办?

日志记录可能会增加一些可观的成本,但如果您仅在调试期间需要它 - 您可以通过 ifdefs 或任何其他方式在发布版本中安全地禁用它,例如:

const bool do_logging = false; // somewhere
// ...
if(do_logging) // branching can be easily removed by optimizer,
               // because do_logging is constant
    // ...
else
    // ...

在你看来,值得还是不值得?

是的,当然。基于标准库设施构建更有用的抽象是常见的做法。

如果我只是为了方便而做这样的事情,以避免在我的所有文件中写入 std:: 或 using::std 怎么办?你觉得这很愚蠢吗?

这取决于您的项目 - 在某些情况下,甚至可以在头文件中使用 using namespace std。但请注意 - 包含此类标题的人可能会面临名称冲突。

在大多数情况下,可以在.cpp 文件的开头使用using namespace std(在inlucdes 之后)。但即使这是不可接受的,你也可以在函数级别使用 using 指令:

void foo()
{
     using namespace std;
     // ...
}

【讨论】:

    猜你喜欢
    • 2014-12-23
    • 1970-01-01
    • 2021-05-23
    • 1970-01-01
    • 1970-01-01
    • 2011-07-30
    • 1970-01-01
    • 1970-01-01
    • 2012-04-19
    相关资源
    最近更新 更多