注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

还东国的博客

行之苟有恒,久久自芬芳

 
 
 

日志

 
 

C++小知识20-C++中一些不常用的前缀介绍(转载)  

2011-09-21 14:02:31|  分类: C++(VC)编程 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

分类: 汇编语言 C/C++ inline汇编语言 C/C++语言 游戏编程 2009-04-09 11:31 516人阅读 评论(0) 

收藏 举报 
  1. placement new 方法
  如:pi = new ( ptr ) int; //placement new
  括号里的参数是一个指针,它指向一个内存缓冲器,new操作将在这个缓冲器上分配一个对象。

Placement new的返回值是这个被构造对象的地址(比如扣号中的传递参数)。placement new主要适用于

:在对时间要求非常高的应用程序中,因为这些程序分配的时间是确定的;
  STL 标准库中 allocator 空间分配器, 就使用了这个语法。
先使用 malloc 分配内存p. 然后 在该内存内构造自己的类对象 new( p ) T1( value ) ; T1 是构造

的类型,value 是类型的值。

   我的ENGINE里面的Allocator就用了这个方法。。。。- -

  2. naked function
  当你的函数内部较简单,用不到太多寄存器。或者需要根据上下文决定一些寄存器变量的时候。可以

用naked 函数。对于一般的函数,如果必要的话,进入函数时编译器会产生代码来保存ESI,EDI,EBX

,EBP寄存器,退出函数时则产生代码恢复这些寄存器的内容。naked call不产生这样的代码。使用

naked函数,我们可以自己编写干干净净的函数,特别是当你代码没有使用这些寄存器的时候。可以像内

联函数一样,省略一些操作。  
  void __declspec( naked ) MyNakedFunction()
  {
  // Naked functions must provide their own prolog.
  __asm
  {
      PUSH       EBP
      MOV ESP, EBP
      SUB ESP, __LOCAL_SIZE
  } 
  // And we must provide epilog.
  __asm
  {
      POP EBP
      RET
  }
  }

  3. 指向类成员函数的指针
  在MFC库中很多窗口基类中调用派生类的消息处理函数。因为windows消息众多,如果为每个消息都设

立虚函数,而每个虚函数都占用4 bytes,那样很多类体积将非常庞大。而且有些地方基类设计时考虑到

派生类在此可能要作些处理,又不想使用虚函数的话也可以使用指向成员函数的指针。如下面的类。如

果派生类没有修改pf成员,在release中 ( *pf )() 将被优化掉。而且使用指向成员函数的指针也不用

定死函数名字.
class animate
{
    typedef void ( animate:: *pfun )( void );
public:
    animate( void ) { pf = static_cast< pfun >( doSomething ); }
    void sleep( void )
   {  
        cout << "animate sleep" << endl;
        ( *pf )();  
   }
    void doSomething( void ){}
    pfun pf;
};


class fish : 

     public animate
{
public:
    fish( void ) { pf = static_cast< pfun > ( test ); }
    void test()
    {
        cout<<"使用基类指针调用派生类非虚函数"<<endl;
    }
};



int _tmain( int argc, _TCHAR* argv[] )
{

      animate* fs = new fish;  
      fs->sleep();  
      delete fs;
      return 0;
}

  4. __declspec( novtable )  

  C++中没有提供类似interface这样的关键字来定义接口,但是Mircrosoft c++中提供了__declspec( 

novtable )来修饰一个类,来表示该类没有虚函数表,也就是虚函数都(应该)是纯虚的
  声明的基类没有 vtable(虚拟函数表), 但还是有vptr指针(指向虚拟函数表)的。所以a1* a = new 

a1; a->hello()执行将会出错 。 而从a1派生的b1是有vtable的。所以 a1* a = new b1; a->hello() 

将调用 b1 的hello函数。如果b1未定义hello函数,那么将调用 a1 函数。其实还是从b1对象的vptr指

向的vtable中索引的函数地址。编译时由于b1中没有定义hello虚函数. vtable 中虚函数hello指向的

是a1类hello函数地址。良好的面向对象设计应该由派生类完成实现。面向对象规则第一条就是基于接

口编程。所以将a1 函数均定义为纯虚函数,a1相当于接口,由派生类b1来实现,这样将抽象与实现之

间解耦合,更符合面向对象规范。
  这样定义的类a1不能调用虚函数。所以a1 类应看成接口。不应生成 a1 类对象。同样程序生成时将

节省a1 类 vtable 的空间。如果有大量虚函数,节省空间还是可观的 函数个数*4. 
  此关键字为vc 所有,其他c++编译器并不支持
   
class __declspec( novtable ) a1
{
public:
  a1( void ) {}
  virtual void hello( void )
  {
      cout << "a hello" << endl;
  }
};

class b1:public a1
{
public :
  b1( void ) {}
  void hello( void )
  {
      cout << "b hello" << endl;
  }
};



  评论这张
 
阅读(940)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017