按:本文是DPWI第6章的笔记。

客户端Slice到C++映射定义的是:怎样把Slice数据类型翻译成C++类型,客户怎样调用操作、传递参数、处理错误。C++映射线程安全,不存在内存管理问题。不建议查看slice2cpp生成的C++映射文件,但建议掌握C++映射规则。



1、模块映射 

module M{...}

映射为

namespace M{...}



2、类型映射 

⑴基本类型

Slice     C++ 

bool   → bool

byte   → Ice::Byte

short  → Ice::Short

int    → Ice::Int

long   → Ice::Long

float  → Ice::Float

double → Ice::Double

string → std::string 



⑵复杂类型 

Slice     C++ 

枚举 →   枚举

结构 →   结构,支持比较符,可用于Slice词典键类型,支持深度复制、赋值。

序列 →   std::vector,可以映射为list,dequeue,数组,范围。

词典 →   std::map。 



3、异常映射 

异常可映射为同名C++类,支持如下操作:

• ice_name  异常的名字。

• ice_clone 多态克隆异常,在不知道异常类型情况下复制异常。

• ice_throw 在不知道某个异常的确切运行时类型的情况下抛出它。

• ice_print  打印异常的名字,或直接使用重载的<<操作符: 



try {

    // ...

} catch (const Ice::Exception & e) {

    cerr << e << endl;

}

出于效率上的考虑,总是通过const引用捕捉异常。这样,编译器就能够生成不调用异常复制构造器的代码(当然,同时也防止异常被切成基类型)。调用操作抛出异常时,该操作的out参数是否赋值无法确定,但是操作的返回值肯定没有返回。



一条异常路径:

• Ice::ConnectTimeoutException

• Ice::TimeoutException

• Ice::LocalException

• Ice::UserException

• Ice::Exception

很少需要以最深派生类型捕获运行时异常,而是以LocalException捕获它们;对细粒度异常处理感兴趣的,主要是Ice运行时实现。



4、接口映射 

module M {

    interface Simple {

        void op();

    };

};

客户端,接口映射到类:

          ↓

namespace IceProxy {

    namespace M {

        class Simple;

    }

}

namespace M{

    class Simple; — 代理类

    typedef IceInternal::ProxyHandle< ::IceProxy::M::Simple> SimplePrx; — 代理句柄

    typedef IceInternal::Handle< ::M::Simple> SimplePtr;

}

namespace IceProxy {

    namespace M {

        class Simple : public virtual IceProxy::Ice::Object {

        public:

            typedef ::M::SimplePrx ProxyType;

            typedef ::M::SimplePtr PointerType;

            void op();

            void op(const Ice::Context&);

            //....

        };

    };

}

IceProxy::M::Simple是服务器Simple接口的客户端代理类,它继承自IceProxy::Ice::Object。接口中的每个操作,代理类都有两个重载的、同名的成员函数。其中一个函数的最后一个参数的类型是Ice::Context——Ice上下文,dictionary<string, string>结构,客户端向服务器发送请求时,将该结构一起发送。



客户端不能直接实例化代理类:

IceProxy::M::Simple s;  ← 错误

客户端只能使用代理句柄SimplePrx访问代理类Simple。代理句柄能够自动管理内存,支持赋值和比较操作符:

SimplePrx prx1 = ...;

SimplePrx prx2(prx1);

prx1=prx2;

assert(prx1==prx2);

cout << prx1 << ';' << prx2 << endl; ← 等效方法 prx->ice_toString()

类似方法:communicator->proxyToString(prx);



BasePrx base = ...; 

DerivedPrx derived = DerivedPrx::checkedCast(base); ← 检查转换:远程访问,失败时返回null。

derived = DerivedPrx::uncheckedCast(base); ← 不检查的转换:不进行远程访问,失败时行为不确定。



代理方法:

Ice::ObjectPrx base = communicator->stringToProxy(...);

HelloPrx hello = HelloPrx::checkedCast(base);

hello = hello->ice_timeout(10000); 

hello->sayHello();



代理比较:

代理同一性比较:==,!=,<,<=,>,>=比较,布尔比较;

代理的对象同一性比较:

bool proxyIdentityLess(p1,p2);

bool proxyIdentityEqual(p1,p2);

bool proxyIdentityAndFacetLess(p1,p2);

bool proxyIdentityAndFacetEqual(p1,p2);



5、操作映射 

对于所有被映射的Slice 类型而言都一样:你可以安全地忽略操作的返回值,不管它的类型是什么——返回值总是通过传值返回。如果你忽略返回值,不会发生内存泄漏,因为返回值的析构器会按照需要释放内存。



in 参数,使用传值或const引用传递;

out参数,使用引用传递。



支持链式调用:

p2->setName(p1->getName()); ← p1,p2为代理



6、异常处理 

SimplePrx p = ...; 

try {

    p->op();

} catch (const SimpleError & t) {

    cout << "Simple Error: " << t.reason << endl;

}

应该总是使用const引用捕捉异常。这样,编译器就能生成不调用异常复制构造器的代码,同时防止异常切成基类型。操作抛出异常后,操作的参数是否已改变不能确定;但是接收操作返回值的变量没有被改写。



7、类映射: 

Slice类映射到同名C++类。

• 每个成员映射为C++类public成员;

• 每个操作映射为虚成员函数;

• 类继承自Ice::Object(代理类继承自Ice::ObjectPrx);

• 两个构造器,一个缺省,一个带有所有成员参数;

• 生成<class-name>Ptr智能指针(<class-name>Prx是代理句柄)。



类继承自Ice::Object基类的成员函数:

• ice_isA:是否支持指定类型ID

• ice_ping:类可达测试

• ice_ids:对象支持的类序列,从根类到最深派生类

• ice_id:类的实际ID

• ice_staticId:类的静态类型ID

• ice_hash:类的哈希值

• ice_clone:多态浅复制

• ice_preMarshal:整编本类前调用

• ice_postUnmarshal:解编本类后调用

• ice_dispatch:请求分派给服务者

• 比较操作符:== != < <= > >=



类成员可见性:

修改类成员的可见性,使用元数据指令:["protected"]



类的构造函数:

类的缺省构造函数,构造每个数据成员,简单内置类型不初始化,复杂类型使用该类型自己的缺省构造初始化。

类的非缺省构造函数,每个数据成员一个参数,可以用一条语句构造和初始化。所有参数按照基类到派生类的顺序,加入参数序列。



类的操作:

类的操作被映射为纯虚成员函数,必须创建派生类,实现这些操作,才能使用类。



类工厂:

有操作的类必须提供类工厂,无操作的类不必提供类工厂。

⑴实现类工厂

class SimpleFactory : public Ice::ObjectFactory {

public:

    virtual Ice::ObjectPtr create(const std::string &) {

        assert(type == M::Simple::ice_staticId());

        return new SimpleI;

    }

    virtual void destroy() {}

};

⑵注册类工厂:

Ice::CommunicatorPtr ic = ...;

ic->addObjectFactory(new SimpleFactory, M::Simple::ice_staticId());

⑶使用类工厂:

现在,每当Ice实例化M::Simple类时,就会自动调用SimpleFactory的create方法,创建SimpleI类,客户端可以使用该类的op方法。



类的智能指针:

Slice 编译器会为每种类类型生成智能指针。对于Slice类<class-name>,编译器会生成叫作<class-name>Ptr 的C++ 智能指针:

    TimeOfDayPtr tod = new TimeOfDayI;

不能在栈上分配类实例,也不能用静态变量定义类实例。类必须由new分配。



智能指针是异常安全的,当抛出异常时,智能指针能够安全地析构。但要注意:在构造器中抛出异常,可能使得智能指针不安全;循环引用的情况下,智能指针也会不安全,这种情况下,可以使用Ice::collectGarbage();  收集因循环引用没有释放的对象。当然只有在循环引用的情况下,垃圾收集器才有用。在没有循环引用的情况下,使用垃圾收集器没有意义。把Ice.GC.Interval 设成5,收集器线程就会每5秒运行一次垃圾收集器。



智能指针的比较只会比较内存地址,即比较两个指针是否指向同一物理类实例。

转自:http://blog.csdn.net/colorado

Slice到C++映射的更多相关文章

  1. ICE学习第三步-----Slice语言

    ICE:Slice语言(一)-编译 Introduce简介 Slice(Specification language for ice)是分离对象和对象的实现的基础的抽象机制.Slice在客户端和服务器 ...

  2. ICE:slice语言常识整理

    ICE:Slice语言(二)--源文件和词法规则:    文件命名    Slice的源文件以.ice为扩展名.   对于大小写不区分的系统(例如DOS),文件的扩展名可以大写,也可以小写,例如Cli ...

  3. Ice分布式程序设计—IceBox(Hello World Application)

    忙了三天,总算浏览完此书.藉此记下 Ice 的 IceBox 服务框架. 在此用 IceBox 框架写 Hello World 程序,即以载体来体现其特性. 第一步:编写 Slice 文件,映射生成 ...

  4. 《effective Go》读后记录

    一个在线的Go编译器 如果还没来得及安装Go环境,想体验一下Go语言,可以在Go在线编译器 上运行Go程序. 格式化 让所有人都遵循一样的编码风格是一种理想,现在Go语言通过gofmt程序,让机器来处 ...

  5. 《effective Go》读后记录:GO基础

    一个在线的Go编译器 如果还没来得及安装Go环境,想体验一下Go语言,可以在Go在线编译器 上运行Go程序. 格式化 让所有人都遵循一样的编码风格是一种理想,现在Go语言通过gofmt程序,让机器来处 ...

  6. python之list,tuple,str,dic简单记录(二)

    切片对象:例子:In [13]: l = [1,23,4,5,5,6,8]In [14]: l[::1]Out[14]: [1, 23, 4, 5, 5, 6, 8] In [15]: l[::2]O ...

  7. 03 Go语言特性

    一.基本注意事项 1.转义字符 \t 一个制表符,代表一次tab \n 换行符 \\ 转义代表 \ \" 转义代表 " \r 一个回车,从当前行的最前面开始输出,会覆盖以前的内容, ...

  8. grunt-css-sprite css 代码中的切片合并

    安装插件:npm install grunt-css-sprite --save-dev grunt-css-sprite主要功能:1.对 css 文件进行处理,收集切片序列,生成雪碧图2.在原css ...

  9. 2.2 Go变量类型

    内置类型 值类型: bool 布尔类型 int(32 or 64), int8, int16, int32, int64 整数类型 uint(32 or 64), uint8(byte), uint1 ...

随机推荐

  1. NSCondition用法

    NSCondition用法 使用NSCondition,实现多线程同步...举个列子 消费者跟生产者... 现在传言6s要出了.. 消费者想买6s.现在还没有6s.消费者等待6s生产. 生产了一个产品 ...

  2. fido-uaf-protocol-v1.0

    EXAMPLE 1: Policy matching either a FPS-, or Face Recognition-based Authenticator { "accepted&q ...

  3. Oracle数据库初探

    一.安装oracle数据库 步骤:转载一个很不错的文档:http://www.linuxidc.com/Linux/2015-02/113222.htm 注意点:安装的时候会check相关依赖,有些可 ...

  4. ubuntu 14.04 安装matlab2015b(破解版),具体软件请访问我的网盘~

    本文章转载自:http://www.cnblogs.com/ttzm/p/5475086.html 1.下载matlab的Unix版本:安装文件放在某目录下(如在Downloads下,则文件的完整路径 ...

  5. 分布式版本控制系统Git-----3.图形化Tortoisegit创建本地库并且提交到远程服务器上

    [前提你已经有了自己的远程仓库帐号密码和HTTP地址] PS:图形化会方便,但是个人认为还是敲命令比较好,会锻炼人的思维和逻辑. 1.首先在任意一个地方创建test目录.若要把test目录放在Git的 ...

  6. Activity的生命周期和启动模式

    Activity的生命周期分析 典型情况下的生命周期.是指在用户参与的情况下,Activity所经过的生命周期的改变. 异常情况下的生命周期.是指Activity被系统回收或者由于当前设备的Confi ...

  7. mysql创建用户、授权[转]

    一, 创建用户: 命令:CREATE USER 'username'@'host' IDENTIFIED BY 'password'; 说明:username - 你将创建的用户名, host - 指 ...

  8. 【转载】Recycle机制

    首先要明白,Recycle机制并不是Java中的垃圾回收机制,而是相当于一种设计模式 思想:当一个对象不再使用时,储存起来,而不是让虚拟机回收,需要的时候再用,避免对象被回收之后重分配 适用范围:对于 ...

  9. ElasticSearch(5)-Mapping

    一.Mapping概述 映射 为了能够把日期字段处理成日期,把数字字段处理成数字,把字符串字段处理成全文本(Full-text)或精确的字符串值,Elasticsearch需要知道每个字段里面都包含了 ...

  10. stl 生产全排列 next_permutation

    #include<stdio.h>#include<algorithm>using namespace std;int main(){ int n,p[10]; scanf(& ...