类库
什么是“STL”?
STL(“标准模板库”)是一个主要由(非常高效的)容器类组成的库,以及一些用于操作这些容器内容的迭代器和算法。
从技术上讲,“STL”这个术语已经不再有意义,因为STL提供的类已经与`std::ostream`等其他标准类一起完全集成到标准库中。尽管如此,许多人仍然把STL看作一个独立的东西,所以你最好习惯听到这个术语。
我在哪里可以获得“STL”的副本?
由于曾经属于STL的类已成为标准库的一部分,你的编译器应该提供这些类。如果你的编译器不包含这些标准类,请获取更新版本的编译器,或者从以下链接下载STL类的副本:
- 一个STL站点:
ftp.cs.rpi.edu/pub/stl
- STL惠普官方站点:
butler.hpl.hp.com/stl/
- 欧洲镜像站点:
www.maths.warwick.ac.uk/ftp/mirrors/c++/stl/
- STL代码备用站点:
ftp.cs.rpi.edu/stl
- SGI 实现:
www.sgi.com/tech/stl/
- STLport:
www.stlport.org
GCC-2.6.3 的 STL hack 是 GNU libg++ 包 2.6.2.1 或更高版本的一部分(它们也可能存在于更早的版本中)。感谢 Mike Lindner。
此外,你可能也应该习惯有些人使用“STL”来包含标准字符串头文件<string>
,而另一些人则反对这种用法。
如何在 Fred*
的 STL 容器(例如 std::vector<Fred*>
)中查找 Fred
对象?
std::find_if()
等 STL 函数可帮助您在 T
容器中查找 T
元素。但是,如果您有一个指针容器,例如 std::vector<Fred*>
,这些函数将使您能够找到与给定 Fred*
指针匹配的元素,但它们不允许您找到与给定 Fred
对象匹配的元素。
解决方案是使用一个可选参数来指定“匹配”函数。以下类模板允许您比较解引用指针另一端的对象。
template<typename T>
class DereferencedEqual {
public:
DereferencedEqual(const T* p) : p_(p) { }
bool operator() (const T* p2) const { return *p_ == *p2; }
private:
const T* p_;
};
现在你可以使用这个模板来找到一个合适的 Fred
对象
void userCode(std::vector<Fred*> v, const Fred& match)
{
std::find_if(v.begin(), v.end(), DereferencedEqual<Fred>(&match));
// ...
}
我在哪里可以获得关于如何使用STL的帮助?
以下是一些资源(随机顺序):
Rogue Wave 的 STL 指南
www2.roguewave.com/support/docs/sourcepro/edition9/html/stdlibug/index.html
或 stdcxx.apache.org/doc/stdlibug/index.html
STL 常见问题:butler.hpl.hp.com/stl/stl.faq
Kenny Zalewski 的 STL 指南:www.cs.rpi.edu/projects/STL/htdocs/stl.html
STL 新手指南
academic1.bellevue.edu/cpphome/stl/STL_newbie.html
SGI 的 STL 程序员指南:www.sgi.com/tech/stl/
还有一些书籍会有帮助。
如何判断你是否有一个动态类型的 C++ 类库?
- 提示 #1:当所有东西都派生自一个单一的根类时,通常是
Object
。 - 提示 #2:当容器类(
List
、Stack
、Set
等)是非模板时。 - 提示 #3:当容器类(
List
、Stack
、Set
等)以指向Object
的指针插入/提取元素时。这使得你可以将一个Apple
放入这样的容器中,但当你取出它时,编译器只知道它派生自Object
,所以你必须使用指针转换将其转换回Apple*
;而且你最好祈祷它真的*是*一个Apple
,因为后果自负。
您可以通过使用 dynamic_cast
使指针转换“安全”,但这种动态测试就是:动态的。这种编码风格是 C++ 中动态类型的本质。您调用一个函数,它说“将这个 Object
转换为 Apple
,如果它不是 Apple
就给我 NULL
”,然后您就有了动态类型:您不知道在运行时会发生什么。
当您使用模板来实现容器时,C++ 编译器可以静态验证 90% 以上的应用程序类型信息(“90% 以上”这个数字是杜撰的;有些人声称他们总是能达到 100%,那些需要持久性的人则获得低于 100% 的静态类型检查)。重点是:C++ 从模板获得泛型,而不是从继承。
什么是 NIHCL?我在哪里可以得到它?
NIHCL 代表“国家卫生研究院的类库”。它可以通过 128.231.128.7/pub/NIHCL/nihcl-3.0.tar.Z
获得。
NIHCL(有些人发音为“N-I-H-C-L”,另一些人发音像“nickel”)是Smalltalk 类库的 C++ 翻译。NIHCL 在某些方面使用动态类型有所帮助(例如,持久化对象)。在另一些方面,它使用动态类型与 C++ 语言的静态类型产生了冲突。
在哪里可以FTP下载“数值计算方法”附带的代码?
此软件是出售的,因此在网上提供是非法的。
另请注意,对《数值计算方法》有一些相当负面的评论,例如 amath.colorado.edu/computing/Fortran/numrec.html
。
以下是按字母顺序排列的其他数值算法来源:
- Isaacson, E. 和 Keller, H.,《数值方法分析》,多佛出版社。
- Kahan, W.,
http.cs.berkeley.edu/~wkahan/
。 - Knuth, Donald E.,《计算机程序设计艺术,第二卷:半数值算法》,Addison-Wesley,1969年。
- LAPACK:线性代数子程序库,
www.siam.org
- NETLIB:来自 ACM Transactions on Mathematical Software 的精选算法,所有这些都经过评审,此外还有大量经过同行非正式审查的算法,
www.netlib.org
- Press 等人著《数值计算方法》。但请注意一些负面评论,例如
amath.colorado.edu/computing/Fortran/numrec.html
- Ralston 和 Rabinowitz,《数值分析初阶:第二版》,Dover。
- Stoer, J. 和 Bulirsch, R.,《数值分析导论》,Springer Verlag,德文版。
为什么我的可执行文件这么大?
许多人对可执行文件的大小感到惊讶,尤其是当源代码非常简单时。例如,一个简单的“hello world”程序可以生成一个比大多数人预期(40KB 以上)更大的可执行文件。
可执行文件可能很大的一个原因是 C++ 运行时库的一部分可能与您的程序静态链接。链接多少取决于编译器关于是静态还是动态链接标准库的选项,取决于您使用了多少部分,以及实现者如何将库分解成各个部分。例如,<iostream>
库相当大,由许多类和virtual
函数组成。使用它的任何部分都*可能*由于相互依赖性而引入几乎所有 <iostream>
代码(但是可能存在一个编译器选项可以动态链接这些类,在这种情况下您的程序可能会很小)。
可执行文件庞大的另一个原因是,如果您开启了调试功能(同样通过编译器选项)。至少在一个众所周知的编译器中,此选项可以将可执行文件大小增加多达 10 倍。
您必须查阅您的编译器手册或供应商的技术支持以获得更详细的答案。
我在哪里可以获得大量关于 C++ 类库的信息?
你应该检查的三个地方(不分先后顺序)
- 《C++ 库》常见问题解答由 Nikki Locke 维护,可带框架和不带框架访问。
- 另外,您应该查看
www.mathtools.net/C_C__/
。他们有大量整理好的资料,目前分为六十多个类别。 - 此外,您还应该访问
www.boost.org/
。他们有一些很棒的东西,其中一些将在下次被提议标准化。
重要提示:这些列表都不是详尽无遗的。如果您正在寻找上述未找到的特定功能,请尝试进行网络搜索,例如使用 Google。另外,不要忘记通过 C++ 库常见问题提交表单帮助下一个人。