`
webcenterol
  • 浏览: 950997 次
文章分类
社区版块
存档分类
最新评论

Prefer C++(一)

 
阅读更多

Prefer C++<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

Written by 李智勇

前言

读了《Eric Raymond对于几大开发语言的评价》一文,觉得其对C++的评价极其偏颇。C++本身支持多典范设计,也就是说你可以完全不用OO,GP而只采用结构化的方法去进行程序设计。这个时候同C相比,效率是基本一致的。而确可以享受到更严格的类型系统检查、inline函数、名字空间、运算符重栽所带来的益处。如果你牺牲一点效率,你还可以使用异常处理。

我以前为项目组成员写过一篇文章,号召大家从C转向C++。现贴出此文,望方家斧正。

1、比C更严格的类型系统

char szBuf[MAX_PATH];

WORD j=szBuf;

C里面是允许的是个警告,而在C++里面则非法是错误。

WORD Add(WORD a,WORD b);

Add(1,szBuf);可能导致灾难性的后果。

更关键的是处理回调函数时:

 比如API函数原型int SetAbortProc(HDC hdc, ABORTPROC lpAbortProc);

调用时有SetAbortProc(hdcPrn, AbortProc)

如果AbortProcABORTPROC类型不符,在c里边将自动转换类型。绝对可能导致灾难性的后果。此时堆栈会如何?

总之C++在防范失误所引起的错误方面做的更好,但绝对不禁止故意打破类型系统的行为。由于必须兼容C,C++做的也不好,警告后还是要做类型转换的。看下面这个例子:

int a=0;

unsigned b=0;

int i;

for(i=10; i>=b; --i)

{

a++;

}

其实这是个死循环。问题出在i和b类型不匹配(编译时这是个警告,而不是错误)。当必须进行比较时,都会被转成unsigned,于是i>=b将永远为true。

2、智能化的资源管理

利用C++的构造和析构函数可以建立非常完善的资源管理机制,尽可能的防止资源泄露。看下面的程序段:

void func1()

{

char* szBuf=malloc(50);//利用C中void* 到其他类型指针的自动转换

--------

free(szBuf);

return ;

}

这样在分配和释放内存之间的任何一个地方,如果需要返回,则必须有这种形式的代码:

if(---)

{ free(szBuf); return 0;}

而一旦忘记释放内存而返回,必将产生内存泄露。

C++类的实例有这样一种特性。在其作用域开始的时候,构造函数被调用,超出作用域时析构函数被调用。利用这一规律来管理资源的最有名的例子是标准库中的智能指针(参看:More Effevtive C++,The C++ Standard Library及The C++ Programming Language。

下面简要说明其原理:

Class A;

void func2()

{

A a; //构造函数被调用

------

return; //析构函数被调用

}

如果在Class A的构造函数中完成相关资源分配,在析构函数中释放内存会怎样?

分配内存后再不用担心释放的问题了。

A大致有如下的形式:

typedef struct tagPoint

{

int x;

int y;

}Point,PPoint;

Class A

{

PPpoint pointer;

SmartPointer(PPpoint p)

{

pointer=p;

}

~SmartPointer()

{

if(pointer)

delete pointer;

}

Point & operator*() const

{

return *pointer;

}

Point * operator->() const

{

return pointer;

}

};

这样用到Point时就可以这样:

A pointer(new Point);//为Point结构分配了内存

pointer->x=5; //存取相关元素

//超出作用域时为Point分配的内存将被自动删除

而为每一个结构都写一个类不划算,所以人们发明了模板。应用模板时A被定义成这个样子:

template <typename T> class SmartPointer

{

SmartPointer(T* p)

{

pointer=p;

}

~SmartPointer()

{

if(pointer)

delete pointer;

}

T& operator*() const

{

return *pointer;

}

T* operator->() const

{

return pointer;

}

private:

T* pointer;

};

这样不管什么结构,都可以用A了。

使用时是这样:

A<Point> pointer(new Point);

pointer->x=5;

//超出作用域时为Point分配的内存将被自动删除

N多人阐述过这个观点,但我觉得在windows下最有用的是附件1。

可实现对Windows下各种句柄的智能化管理。

作者:Jeffey Richter 2000年第四期msdn杂志,win32 Q&A专栏

读懂这个例子需要一点模板和符号重载的知识。

用起来很简单:

比如对于文件句柄,有:

CensureCloseHandle hHandle=CreateFile(---);

WriteFilehHandle;

----------

不用调用CloseHandle了,超出作用域它将被自动调用。

最嚣张的应用是有引用记数的智能指针。

见附件2。(Come from the C++ standard library)

3、强大的inline(C不支持这个吧!)

第一次看Link-time Code GenerationMatt Pietrek MSDN magazine 2002 5别的也没记住,就记了个通过链接器自主选择那些函数可以做inline可大幅度提高性能。后来自己就在vc++上试了一下,结果还是真恐怖,先说性能最多能提高多少,看下面的程序,并猜猜inline函数所花费的时间:

int add(int a,int b)

{

return a+b;

}

inline int addinline(int a,int b)

{

return a+b;

}

都是以这种形式进行调用:

int b;

for(int j=0;j<50000;j++)

{

b=add(60,70);

}

假设add()所花费的时间是:88964ns(vc++ 6.0 release 版本下),那么addinline所花费的时间是多少?

真实结果是0,也就是说addinline函数根本不存在。被优化后,剩下的只是一个值0x82。当然这是一个极端的例子,但从另一个角度讲把适当的函数做成inline实际上是给编译器,连接器做出更大优化的机会。

inline的另一个优势。

大家都知道,函数调用要处理堆栈(很少是寄存器)。这样就有一部分进栈和出栈的指令,这部分代码对于inline是没有的。

for(int j=0;j<50000;j++)

{

b=add(j,j+1);

}

for(int p=0;p<50000;p++)

{

b=addinline(p,p+1);

}

cout<<b;//必须使用一下b

此时所耗费的时间两者分别为:

1.10619e+006ns 和331754ns

分享到:
评论

相关推荐

    Google C++ Style Guide(Google C++编程规范)高清PDF

    Therefore, we prefer to minimize includes, particularly includes of header files in other header files. You can significantly minimize the number of header files you need to include in your own ...

    effective c++

    - **书籍背景**:《Effective C++》由Scott Meyers撰写,侯捷翻译,是C++领域内一部非常著名的指南类书籍。该书旨在帮助程序员更好地理解和运用C++语言,通过一系列明确且实用的规则来提升代码的质量和效率。 - **...

    c++ Effective STL(中文+英文)

    Prefer range member functions to their single-element counterparts...12 Item 6. Be alert for C++'s most vexing parse...................................................20 Item 7. When using containers...

    Google C++ Style Guide_英文版.pdf

    ### Google C++ Style Guide #### Table of Contents - **C++ Version** - **Header Files** - Self-contained Headers - The #define Guard - Forward Declarations - Inline Functions - Names and Order ...

    C++ GUI Qt4编程第二版

    Sure, there are the obvious answers: Qt's single-source compatibility, its feature richness, its C++ performance, the availability of the source code, its documentation, the high-quality technical ...

    C++ 핵심 가이드라인 한글화 프로젝트 (C++ Core Guidelines).zip

    C++ 핵심 가이드라인(C++ Core Guidelines)은 C++ 언어의 최신 개발 패턴과 규칙을 제공하는 참고 자료입니다. 이 가이드라인은 Bjarne Stroustrup, 주도하에 Microsoft와 LLVM 프로젝트가 공동으로 제작하였습니다....

    Effective C++(第三版)

    条款01:视c++ 为一个语言联邦 view c++ as a federation of languages 条款02:尽量以const, enum, inline替换 #define prefer consts,enums, and inlines to #defines. 条款03:尽可能使用const use const ...

    Using LUA with Visual C++ (Introduction)

    LUA is a scripting language, its power lies in the fact that it can be embedded in your C++ programs. Scripts give you the possibility to change the behaviour of your C++ programs without any need to ...

    Copy Constructors and Assignment Operators终极解释

    在C++编程语言中,复制构造函数(Copy Constructor)和赋值运算符(Assignment Operator)是两个非常关键的概念,特别是在处理对象的拷贝和赋值时。它们默认由编译器提供,但通常需要根据具体需求进行自定义,以确保正确...

    ClassLoader运行机制 自己写的

    在某些情况下,比如WebLogic中的`prefer-web-inf-classes`配置项为true时,即使系统或应用类路径中有相同的类,WebLogic也会优先加载Web-INF目录下的类。这使得Web应用可以覆盖系统或应用级别的类定义,提供了更高的...

    程序员面试刷题的书哪个好-effective-cpp-note:EffectiveC++、MoreEffectiveC++和Effective

    一、让自己习惯C++ (Accustoming Yourself to C++ 11) 1. 视C++ 为一个语言联邦 11(View C++ as a federation of languages 11) 主要是因为C++是从四个语言发展出来的: C的代码块({}), 语句,数据类型等, object-...

    Android-使用Android8.1上的新NNAPI运行神经网络的示例

    options.setExecutionPreference(Interpreter.Options.ExecutionPreference.PREFER_NNAPI); interpreter = new Interpreter(modelFile, options); ``` 4. 执行预测:将输入数据传递给模型,获取预测结果。 ```java ...

    linux时间同步ntp服务的安装与配置

    再加上我们的时间同步服务端的IP地址或者域名即可,其中prefer选项表示优先使用该时间同步服务器 #server 0.centos.pool.ntp.org iburst #server 1.centos.pool.ntp.org iburst #server 2.centos.pool.ntp.org ...

    simual-04.rar

    navigational aids and waypoints) and on-screen text and menus (similar to the existing modeless ATC menus), and two new C++ samples have been added to demonstrate the new functions. The functions for...

    20220406-CMake立大功:glibc更新引发的陈年旧案-panruizhe1

    然后,我们怀疑是CMake的bug,于是查看了CMake的commit记录,发现了一个相关的commit(Kitware/CMake commit 68285bc8a91),该commit将FindThreads.cmake模块修改为遵从THREADS_PREFER_PTHREAD_FLAG变量的设置。...

    Turbo Assembler 5 (TASM)

    TASM has full 8088, 8086, 80286, 80386, i486, and Pentium support, as well as interface support for C, C++, Pascal, FORTRAN, and COBOL. A full-screen interactive debugger (Turbo Debugger) is also ...

    VclZip pro v3.10.1

    VCLZip Native Delphi Zip/UnZip Component! (VCLZip Lite: Version 2.23 April 14th, 2002) (VCLZip Pro: Version 3.10 Buid 1 - November 25th, 2007) IMPORTANT: If installing the registered version, ...

    学习代码收藏 学习代码收藏

    "prefer" 可能指的是“偏好”或“首选”,而 "OA" 可能是 "Office Automation" 的缩写,暗示这可能涉及到办公自动化相关的编程实践,比如使用Python进行自动化任务,或者可能是其他编程领域的优选代码片段。...

Global site tag (gtag.js) - Google Analytics