我正在开发一个用于命令行应用程序的小型库。这个库的一个特性是它的主类可以在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
构建用户。
答案 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)