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

秒大刀 博客

好好学习 天天向上

 
 
 

日志

 
 
 
 

C++/CLI 学习笔记  

2009-02-25 23:05:47|  分类: C/C++ |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
  • 类型定义语法:
    public ref class Block {}; // 引用类型定义
    public value class Vector {}; // 值类型定义
    public interface class IMyFile {}; // 接口定义
    public enum class MyEnum{}; // 枚举定义
    public ref class Shape abstract {};
    public ref class String sealed {};
    public ref class State abstract sealed {}; //一个类既声明为抽象类也声明为密封类。这是一种被称为静态类的特殊情况
  • 继承:只支持公有方式的单继承。public关键字可忽略
    ref class My : File{}; 
    ref class My : public File{};
  • 跟踪句柄:引用类类型的对象用一个新的声明性符号(^)声明,正式的表述为跟踪句柄,不正式的表述为帽子
  • new:
    Button^ button1 = gcnew Button;         // OK: 托管堆
    int * pi1 = new int;                                 // OK: 本机堆
    interior_ptr<Int32> pi2 = gcnew Int32; // OK: 托管堆  interior_ptr通常表示一个对象的地址,这个对象可能(但不必)位于托管堆上。如果指向的对象确实位于托管堆上,那么它在对象被重新定位时被透明地更新。
  • nullptr表示空跟踪句柄,nullptr可以转化成任何跟踪句柄类型或者指针,但是不能提升为一个整数类型
  • 数组定义:
    array<Object^>^ myArray = gcnew array<Object^>(2);
    array<String^,2>^ myMat = gcnew array<String^,2>(4,4);
    array<Object^>^ myArray = gcnew array<Object^>(4){ 1, 1, 2, 3 };
  • 对象析构:
    ~ClassName析构函数被内部重命名为 Dispose()方法,并且引用类自动扩展以实现 IDisposable接口
    !ClassName终止器将被内部合成为 Finalize()方法,并在有基类的情况下在其末尾会插入基类的 Finalize()方法的调用。如果析构函数被显式地调用,那么终止器会被抑制。
    可以像传统C++那样定义一个“栈对象”,当对象离开作用域的时候会自动调用Dispose方法,这类似于C#的using语法
    对跟踪句柄执行delete相当于显式的Dispose调用。
  • 属性和索引器:
    property double x  // 普通属性
    {
       double get()
       {
          return _x;
       }
    private// 可以显式指定,也可省略
       void set( double newx )
       {
          _x = newx;
       }
    }
    property double x; //等价的简洁属性语法
    property int Row [int]  // 普通索引器
    {
       int get( int r );
       void set( int r, Vector^ value );
    }
    property int default [int,int]  // 默认索引器。当指定了 default索引属性时,下面两个名字被保留:get_Itemset_Item。这是因为它们是 default索引属性产生的底层名称
    {
       int get( int r, int c );
       void set( int r, int c, float value );
    }
  • 代理和事件
    delegate void DblClickEventHandler( String^ ); 
    event DblClickEventHandler^ OnDblClick;  // 隐式事件声明
    // 显式事件声明,每种子操作的可见性都是可以定制的
    f^ _E;
    event f^ E1
    {
    public:
       void add( f^ d )
       {
          _E += d;
       }
    protected:
       void remove( f^ d )
       {
          _E -= d;
       }
    private:
       void raise( int i )
       {
          if ( _E )
             _E( i );
       }
    }
    // 事件的挂载和卸载
    pE->E1 += gcnew f( pE, &E::handler );
    pE->E1 -= gcnew f( pE, &E::handler );
  • 虚函数:
    virtual void f();  // 虚函数声明
    virtual void f()=0; // 纯虚函数声明
    virtual void f() abstract;  // 纯虚函数声明
    virtual void f() sealed; // 虚函数的封闭
  • 支持运算符重载
    static Vector^ operator /( const Vector^, double );
  • 自定义类型转换
    ref struct MyDouble
    {
    public:
       static operator MyDouble^ ( int i );
       static explicit operator int ( MyDouble^ val );
       static explicit operator String^ ( MyDouble^ val );
    };
  • 显式接口实现
    public ref class R : public ICloneable 
    {
       // 通过 ICloneable 使用 ...
       Object^ InterfaceClone() = ICloneable::Clone;  // 要求为显式重写的接口成员赋予一个在类中唯一的名称
       // 通过一个 R 对象使用 ...
       virtual R^ Clone() new;
    };
  • 虚函数重写
    虚函数不能重写不可访问的基类虚函数,继承的方法不必沿用同样的访问级别
  • static const整型将会在编译时展开而不纳入到CLR常量,可以通过literal int LOG_DEBUG = 4 语法显式的指明为CLR常用
  • 枚举和整数之间的转换:safe_cast<int>(myEnum),用static_cast也可以做到,但前者会产生正确性验证的MSIL代码
  • 指针
    V* 可指向非托管堆和栈地址
    V^ 可指向托管堆的地址,若为值类型,则为装箱地址
    interior_ptr<V> 指向任何地址,若为托管堆地址,则会自动同步更新
    pin_ptr<V> 订住指针,pin_ptr<V>对象超出作用域后将会解除pin
  • 变长参数
    int Add(...array<int>^ args){}
  • Type
    String::typeid == str->GetType()
  • 类型转换
    static_cast<T>:不会检测正确性的暴力转换,可能返回错误的结果,不建议使用
    dynamic_cast<T>:失败情况下会返回nullptr
    safe_cast<T>或者(T)的C风格转换:失败时将抛出InvalidCastException异常
  •  

    参考:

    转换指南: 将程序从托管扩展 C++ 迁移到 C++/CLI

    C++/CLI

    Language Features for Targeting the CLR

    Standard ECMA-372 C++/CLI Language Specification


    2011-5-4

        和大量C++代码互动可能会出现"error LNK2028: 无法解析的标记……__clrcall……"的链接错误,可以使用“/clr”选项,而不是默认的“/clr:pure”。也可以采用#pragma managed指令将非托管头文件包起来:

    #pragma managed(push, off)
    #include <***.h>
    #include <***.h>
    #pragma managed(pop)

    参考:

    2011-5-20
    auto_handle Automatic resource management which can be used to embed a virtual handle into a managed type.
    auto_gcroot Automatic resource management (like auto_ptr Class) which can be used to embed a virtual handle into a native type.

    2012-2-14
    若采用了C++/CLI,则会有宏 __cplusplus_cli 定义。

    2013-2-6
      评论这张
     
    阅读(7786)| 评论(0)

    历史上的今天

    评论

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

    页脚

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