二战时期,尼康再度作为军工企业获得了巨大成长,其从业员工一度达到二万五千余名。日本投降以后,尼康不得不再次完成从军工光学到民用光学产品的转换。由于没有了买家(老东家日本海军不存在了)无产品可作,其员工曾一度减至 1,724
名。当时其制品转为望远镜、相机、显微镜、测量计等。在这个时期,尼康开始了小型旁轴相机的开发。这种小型相机的名称为 nikon 即现在的名称尼康。“Nikon”商标于 1946 登录之后的一段时间里,尼康又先后推出了尼康
M(于1950年),尼康 S 系列(于1951),s2 于 1954 年,sp 于 1957 年,s3 于 1958 年以及 s4 于 1959 年。尼康 M 在 1950 年 12 月 10 日的 New York Times
上被高度评价。尼康品牌在世界范围内开始被广泛认知,并获得好评。
Life 的摄影师―Robert Capa―D.D.Duncan―H.Walker--C.
Mydans―等经由日本去朝鲜取材,它们对尼康相机的高度评价,奠定了尼康神话的基础。(注解--最初他们是把尼克尔镜头改造后装在莱卡和康泰时上用、后来尼康改良了相机的胶片格式即采用了莱卡判――今天的135格式。所以这些摄影师干脆直接实用了尼康相机和镜头--好像是s2
并且在朝鲜战争中,这些尼康都很争气。未出故障。之所以会出现这种情况,一方面是因为日本的地理优势,另一方面当时的尼克尔镜头从多个方面却实超越过蔡斯。)
3、F 诞生和 NASA 用相机的开发
在尼康大举开发旁轴 s 系列相机的五十年代。以米兰达品牌为代表产品的旭光学工业(现宾德)及美能达等企业生产德单反相机接连发表。而尼康则优先进行了尼康旁轴旗舰 SP 的研发生产,这使得尼康进入单反市场比其他厂家要晚一段时间。1959
年大名鼎鼎的尼康 F 登场。因其价格非常高昂,所以开始的一段时间里只是叫好不叫座。但是在后来的使用中、其优异性能和质量被人们认可(专业摄影师的系统中必有尼康 F
的评价广为流传),加之之前其旁轴相机的成功,尼康神话遂逐渐成为共识。在此之后,尼康又接连推出了系列单反相机,好评如潮,其作为顶级 135 单反相机生产企业的形象得以建立和巩固。尼康 F 的改造版本成为 NASA 的阿波罗 15
号搭载用机,其后续产品 F3、4、5 也享有相同待遇。尼康所取得的成功,为当时的日本产业界打了一剂强心针。之前,日本产品的口碑很差,而尼康的高质量,高性能,改变了世人的看法,这是在 SONY
松下等企业出名之前的事情。尼康的成功,也带动了当时日本整个相机产业的崛起。
尼康与佳能的竞争在其旁轴时代就开始了。不过真正发展到大战的程度,则要从七十年代出头说起。尼康凭借 F 系列于高端 135 单反上长期独领风骚。佳能在 1971 年推出了 F-1,含有超越打败 F
系列的意思,从此两家在单反市场展开了炽烈的市场竞争。相传 F-1 在刚推出时,佳能曾暗自以接近新机价格高价收购尼康 F,以帮助摄影师们换用佳能 FD 系统。1985 年美能达推出了首部实用的 AF
单反相机,1985年也被称为自动对焦系统元年。在 AF 时代,佳能采用了新的 EF 卡口标准,尼康则继续采用 F 卡口规格进入 AF 市场。也正是从那时候起,市场格局由 C 追 N,渐变成了 N 追 C。
D型镜头:Distance 焦点距离数据传递技术
代表镜头可回传对焦距离信息,作为 3D(景物的亮度,景物对比度,景物的距离)矩阵测光的参考以及 TTL 均衡闪光的控制。1992年推出。
代表镜头:28-105mm f/3.5-4.5D AF Zoom-Nikkor
CRC:Close Range Correction 近摄校正
采用浮动镜片设计,保证近摄时光学素质不下降,例如AIS 24/2.8、AF 85/1.4D IF之类均采用了CRC技术。
DC : Defocus-image Control 散焦影像控制
尼康公司独创的镜头,可提供与众不同的散焦影像控制功能。镜头的前端有一个散焦定位转环,该环上的光圈值从F2到F5.6共4挡,分别标在环的左右,用R(后景散焦)与F(前景散焦)来指示。这是一种特殊的定焦镜头,其最大特点在于容许对特定被摄体的背景或前景进行模糊控制,以便求得最佳的焦外成像,这一点在拍摄人像时非常有价值,它还可以帮助我们根据所想要表现的来控制照片的各个部分,这也是其它厂家同类镜头所无法比拟的。
目前尼康只有2支DC镜头:AF DC 105mm f/2D、AF DC 135mm f/2D
ED : Extra-low Dispersion超底色散镜片
是指这支镜头内含 ED 镜片,最大限度降低镜头色差(chromatic aberration),从而保证镜头有优异的光学表现。
代表镜头:80-200mm f/2.8D ED AF Zoom-Nikkor
G型镜头
与D型镜头不同的是,该种镜头无光圈环设计,光圈调整必须由机身来完成,同时支持3D矩阵测光。这样的设计减轻了镜头重量,降低了生产成本。该种镜头与F5、F100、F80、F65、F60、F55、F50、F401、PRONEA和D1机身完全兼容,对于F4、F90\F90X、F70、F801和F-601等机身,只能使用程序曝光和快门优先曝光模式。与剩下的其他机身不兼容。G型Nikkor镜头操作更为简便,理论上没有误操作,因为它无需手动设置最小光圈。这是塑料AF镜头的延续,针对那些几乎从不手动设置镜头的摄影者。现在Nikon有将G型头推广的趋势。
代表镜头:28-80mm f/3.3-5.6G AF Zoom-Nikkor
IF : Internal Focusing内对焦技术
所谓内对焦是指镜头在对焦时,前后组镜片都不移动,而由镜头内部的一个对焦镜片组(focus lens group)的浮动来完成对焦,对焦时镜头长度保持不变。IF技术的采用使快速而安静的对焦变为可能。
代表镜头:85mm f/1.4D IF AF Nikkor
DO:Multi- Layer Diffractive Optical Element 多层衍射光学元件
Canon于2000年9月4日宣布研制成功世界上第一片用于照相机摄影镜头中的“多层衍射光学元件”。多层衍射光学镜片同时具有萤石和非球面镜片的特性,所以该镜片的推出,是光学工业的一个里程碑。衍射光学元件最重要的特性是波长合成结像的位置与折射光学元件的位置是反向的。在同一个光学系统中,将一片MLDOE与一片折射光学元件组合在一起,就能比萤石元件更有效地校正色散(色彩扩散)。而且,通过调整衍射光栅的节距(间隙),衍射光学元件可以具有与研磨及抛光的非球面镜片同样的光学特性,有效地校正球面以及其他像差。
代表镜头:EF 400/4 DO IS USM
L: Luxury 豪华
佳能专业镜头的标志。和消费级镜头相比,L头带有研磨非球面镜片、UD(低色散)、SUD(超低色散)或者Fluorite(萤石)镜片,这些是镜头出色的光学质量的重要基础。通常镜头的构造质量也要优秀很多。其标志为镜头前端的红色标线,是佳能的高档专业镜头。
代表镜头:EF70-200/2.8 LU
IS:Image Stabilizer 影像稳定器
影像稳定器是通过修正光学部件的运动减小手颤动对成像的影响,所以也称防手震镜头。在IS镜头中,装有一个陀螺传感器,它能检测手的振动并把它转化为电信号,这个信号经过镜头内置的计算机处理,控制一组修正光学部件作与胶片平面平行的移动,抵消手颤动引起的成像光线偏移。这个系统能够有效地改善手持拍摄的效果,对一般情况而言,IS镜头允许您使用比理论上低两级的快门速度。也就是说,您用普通300毫米镜头时,只能选择1/250秒以上的速度,而使用300毫米IS镜头就可以用1/60秒拍出清晰的照片。
代表镜头:EF28-135/3.5-5.6 U IS
大多数 C++ 开发人员在他们的代码中都广泛使用了标准模块库 (STL)。如果您是其中的一员,并且正在直接使用即装即用的 STL 和 Visual C++ 6.0,则在内存不足的条件下,您的应用程序就处于崩溃的高度危险的状况下。产生此问题的原因是,检查运算符 new 是否失败是一种非常少见的做法。更糟糕的是,当 new 确实失败时,响应不是标准的。有些语言编译器返回 NULL,而其他语言则引发异常。
另外,如果您正在 MFC 项目中使用 STL,要注意 MFC 有其自己的规则集。本文将讨论这些问题,说明如何更改 Visual C++ .NET 2003 中的默认行为,并概述了如果使用 Visual C++ 6.0 所必须进行的更改,这样当运算符 new 失败时,您就可以安全地使用 STL 了。
有多少开发人员检查运算符 new 是否失败?有必要总是检查失败吗?我见过大型、复杂的用 Visual C++® 6.0 编写的 C++ 项目,其中在整个代码基中没有一项检查查看 new 是否返回 NULL。注意,我说的是检查 new 是否返回 NULL。在所有版本的 Visual C++(一直到版本 6.0)中,运算符 new 失败时的默认行为都是返回 NULL,而不是引发一个异常。(有关更多信息,请参见知识库文章 167733,但不要实现文中给出的解决方案。在本文后面我将解释为什么不应该实现解决方案)。
Visual C++ .NET 的默认行为已经更改,包括版本 7.0 (Visual C++ .NET 2002) 和 7.1 (Visual C++ .NET 2003),当运算符 new 失败时,该行为会引发一个异常。虽然 Microsoft® .NET Framework 下的这种新行为遵循该 C++ 标准并深受欢迎,但需要注意,它可中断所有移植过来的 Visual C++ 6.0 样式代码的运行时行为,而这些代码不希望运算符 new 引发异常。如果您正在用 Visual C++ .NET 进行开发,您会发现这里产生的问题已经被解决。如果您还未使用某一种版本的 .NET Framework,本文将探究运算符 new 返回 NULL 时的隐含与不兼容等严重问题,这些问题适用于所有版本的 Visual C++ 编译器,包括 6.0 版本以及更高的版本。
背景
当 Microsoft 发布第一版的 Visual C++ 编译器时,其主要作用是支持 MFC 框架。对于所有实际应用来说,Visual C++ 和 MFC 被看作是一种产品。多年来,MFC 和 Visual C++ 编译器都已经成熟。同时,Visual C++ 编译器已经成为拥有其自己权利的产品,不必依赖于 MFC 并支持其他技术,如活动模板库 (ATL)、标准模板库 (STL),以及其他多种技术。现在,MFC 只是 Visual C++ 编译器支持的多种库的一种。因此,现在使用不带 MFC 的 Visual C++ 开发项目的情况是非常普遍的。
我是在发现运算符 new 失败后,我的 STL 代码会出现异常行为时才开始撰写这篇文章的。令我惊讶的是,我发现运算符 new 失败时,Visual C++ 6.0(以及支持 STL 的所有以前版本)与 STL 不兼容。我正在进行的项目没使用 MFC,所以我的观察仅基于非 MFC 代码的情况。当我开始研究基于 MFC 的示例时,我发现 MFC 定义了运算符 new 的很多不同行为。钻研本篇文章之前,我想小结一下内存分配失败时运算符 new 的行为。为了更好地进行比较,我将讲述 Visual C++ .NET 下的行为,因为它与以前的版本不同。
C++ 标准声明运算符 new 在失败时应引发异常。具体地说,引发的异常应该是 std::bad alloc。这是标准行为,但 Visual C++ 6.0 中的行为取决于您如何使用它以及使用什么样的版本。图 1 显示了内存分配失败时运算符 new 的 Visual C++ 行为。
可以看到,只有 Visual C++ .NET 中的非 MFC 代码才遵循该标准。如果您使用 MFC,那么 new 将引发一个异常,但其类型不正确。如果您使用的 STL 的实现包含 catch (std::bad alloc) 语句,用该语句来处理内存失败的情况,那么起作用的即装即用的唯一组合方式就是无 MFC 的 Visual C++ .NET。Visual C++ 6.0 随附的 STL 实现使用 catch(...) 来处理运算符 new 失败,因此如果您使用 MFC,当运算符 new 失败时,Visual C++ 6.0 随附的 STL 实现将正确操作。
假定 MFC 提供的运算符 new 实现引发异常 (CMemoryException),并且在 Visual C++ .NET 中非 MFC 的运算符 new 也引发异常 (std::bad::alloc),那么我认为在所有实际应用中,这些情况将不会产生问题。那么,在基于 Visual C++ 6.0 的项目中不使用 MFC 而使用 STL,这种常见方案又会怎样?这是本文剩余部分将讨论的重点。
运算符 New 返回 NULL
回到本文开始部分的问题,一般来说,不检查运算符 new 返回的指针值是否为 NULL 有两个原因,其一为:运算符 new 从来就不会失败,或者运算符 new 会引发异常。
该处理程序的测试工具程序非常简短,如图 6 所示。在大多数计算机上,该测试代码的分配将会引起即时失败。示例代码导致非法的堆分配大小,无需实际执行分配即导致立即失败。遗憾的是,如果您持续分配了大块的内存,直到实际堆分配发生失败,您将不能对代码进行调试,因为 Visual C++ IDE 在内存不足的情况下总是要崩溃的。为了构建该测试程序,下载示例文件。在 Visual C++ 6.0 中打开 Testnew_throw.cpp 文件,从 Build 菜单选择 Build。接受创建一个默认工作区的提示。如果逐句调试代码,您会验证现在在失败时运算符 new 将引发 std::bad_allocc 类型的异常。