按:本文是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. s14 第5天 时间模块 随机模块 String模块 shutil模块(文件操作) 文件压缩(zipfile和tarfile)shelve模块 XML模块 ConfigParser配置文件操作模块 hashlib散列模块 Subprocess模块(调用shell) logging模块 正则表达式模块 r字符串和转译

    时间模块 time datatime time.clock(2.7) time.process_time(3.3) 测量处理器运算时间,不包括sleep时间 time.altzone 返回与UTC时间 ...

  2. 郑州尚学堂:如何看待ARM的各种模式?

    嵌入式设备已经越来越与我们的日常生活密切相关了,由此带来了ARM的高速发展.就拿我们的手机来说吧,几乎所有的手机都是ARM体系的.这里大致介绍下ARM 的7种执行模式. ARMv4以上版本的CPU任何 ...

  3. Java--最大子序列和实现

    package com.dongbin.test; /** * 最大子序列和 --分治法 * * @author dongbin * */ public class MaxSubListSum { / ...

  4. WPF关于“在“System.Windows.Markup.StaticResourceHolder”上提供值时引发了异常。”问题解决办法

    在WPF中添加样式,在MainWindow.xaml使用自定义按钮FButton时报错,报错信息如下: "System.Windows.Markup.XamlParseException&q ...

  5. Servlet综述

    Servlet 是在服务器上运行的小程序.这个词是在 Java applet 的环境中创造的.虽然后者已很少被使用,但 servlet 却发展的很好.是一般面试都会常考的知识. 由来 servlet ...

  6. Linux服务器导入导出SVN项目

    导出项目: # svnadmin dump /var/svn/pro1 > /mydata/pro1.backup 导入项目: 新建项目仓库: # svnadmin create /var/sv ...

  7. 第七十八节,CSS3文本效果

    CSS3文本效果 一.文本阴影 CSS3提供了text-shadow文本阴影效果,这个属性在之前讲过,只是没有涉及浏览器 支持情况. 浏览器支持情况 text-shadow       Opera   ...

  8. CentOS7 安装 Mysql 服务

    我希望所有的软件包都用 rpm.yum 安装,这样卸载.升级.管理方便,可是自带的 yum 仓库里面没有 mysql-server 或者不是最新的,我需要安装MySQL官方的 yum 仓库, http ...

  9. HDU 1564 Play a game

    Description New Year is Coming! ailyanlu is very happy today! and he is playing a chessboard game wi ...

  10. Node.js:全局对象

    概要:本篇博客主要介绍了node.js中的全局对象. 在JavaScript中,通常window是全局对象,而node.js中的全局对象是global,所有全局变量(除了global本身之外)都是gl ...