包括一个大的头文件以使用一个对象作为默认参数

时间:2018-03-08 04:17:20

标签: c++ include header-files iostream default-arguments

我正在开发一个用于命令行应用程序的小型库。这个库的一个特性是它的主类可以在ostream中生成文本,如下所示:

#include <iostream>    

class MyClass {
    std::string a;
    std::string b;

    void printToStream(std::ostream& stream = std::cout)
    {
        stream << "a: " << a << " | b: " << b << std::endl;
    }
}

我的问题是关于使用std :: cout作为默认参数。 它只是为了使库更容易使用,因为它面向命令行应用程序,如前所述,所以大多数时候所需的输出应该是标准输出,但是如果用户需要不同的输出流他们可以自己提供一个。

这是我的库中唯一使用iostream的东西的点,所以我想知道是否有这样的默认参数会导致任何效率损失。根据我的理解,iostream是一个庞然大物,超过25,000行代码,如果用户提供自己的输出流,它将被无偿地包含在内。

此外,据我所知,如果iostream最终未在此处使用,编译器可能足够智能,不能在最终可执行文件中包含cout中的任何内容,但我想知道完整的影响这个包含在我的库中 - 以及是否有更好的方法将cout实现为默认参数,而不必在没有必要的情况下针对iostream构建用户。

1 个答案:

答案 0 :(得分:1)

答案非常简短:在您的编程工作方面,可能不是您最重要的决定。

更长的回答,这并不能比上面更多地告诉你,但如果你这样倾向,你仍然会觉得有趣。

这是一个高度依赖于您的环境敏感度的问题之一。如果您正在为具有256KB RAM的系统构建,并且您必须适应所有这些应用程序,操作系统和数据库引擎,显然,千万字节的应用程序空间是宝贵的。另一方面,在我的笔记本电脑或台式机上,一方面内存比手指计数更多兆字节,可能一点都不用担心。在具有几兆字节RAM的范围系统的中间,不是保持代码大小下降的首要任务。

我使用单个头文件快速编写了两个简单的应用程序:

<强> myclass.h:

#include <iostream>    

class MyClass {
public:
    std::string a;
    std::string b;

    void printToStream(std::ostream& stream = std::cout)
    {
        stream << "a: " << a << " | b: " << b << std::endl;
    }
};

然后一个&#34;使用&#34; printToStream

<强> uses.cpp:

#include "myclass.h"

int main()
{
    MyClass m;
    m.a = "Hello";
    m.b = "World";
    m.printToStream();
}

g ++ -O1中的大小:3502字节,clang ++ -O1:4409

和一个不使用printToStream的人:

<强> nouse.cpp:

#include "myclass.h"

int main()
{
    MyClass m;
    m.a = "Hello";
    m.b = "World";
}

g ++ -O1中的大小:2349字节,clang ++ -O1:2923

大小差异大约为1500字节,clang ++ -O1为1200字节,g ++ -O1为1200字节。整个代码大小约为2.5-4KB,因此在这个小例子中它占整体大小的30%左右。显然,这远非线性 - 一旦你使用std::cout,初始化就可以用于它的所有用途。

如果我将myclass.h文件修改为#include <string>,并完全删除对流的引用,则会进一步从nouse.cpp生成的二进制文件中删除大约300字节的代码。这表明包含<iostream>的JUST会在你的二进制文件中添加一些代码。但是,使用<ostream>代替<iostream>对生成的二进制文件没有任何影响。

我也尝试删除std::cout默认参数。这根本没有区别(代码更改除了uses.cpp中有附加参数),因此大小相同。它对nouse.cpp也没有影响 - 额外的代码仍然可以初始化cout

同样,在主文件中包含<ostream>然后包含<iostream>uses.cpp的大小没有影响(不使用默认参数)。

我也尝试了-O2,它使代码更改大小(g ++更大,clang ++更小),但相对差异不是很大。

显然,这是两个最流行的开源C ++编译器的两个实例。其他编译器可能会给出略有不同的结果。如果它非常重要,请使用您的编译器进行测试。

随Ubunt提供的g ++版本:7.2.0,clang ++:7.0.0(使用git版本的源代码来构建clang 16003bcdb4287aab3b87300d9e95f9b49ce52c1c,llvm 45ebd75cc103838da0b3938ac5d044ec8a7ff17b)