Slice到C++映射

按:本文是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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第 1 章引言 1 1.1 引言 1 1.2 Internet Communications Engine (Ice) 3 1.3 本书的篇章结 4 1.4 排字约定 4 1.5 源码示例 5 1.6 联系作者 5 1.7 Ice 支持 5 第 Ice 综述 7 第 2 章 Ice 综述 9 2.1 本章综 9 2.2 Ice 架构 9 2.3 Ice 服务 21 2.4 Ice 在架构上提供的好处 23 2.5 与 CORBA 的对比 25 第 3 章 Hello World 应用 33 3.1 本章综 33 3.2 编写 Slice 定义 33 3.3 编写使用 C++ 的 Ice应用 34 3.4 编写使用 Java的 Ice 应用 41 3.5 总结 48 第 Ice 核心概念 51 第 4 章 Slice 语言 53 4.1 本章综 53 4.2 引言 53 4.3 编译 54 4.4 源文件 57 4.5 词法规则 59 4.6 基本的 Slice 类型 62 4.7 用户定义的类型 63 4.8 接口、操作,以及异常 70 4.9 类 92 4.10 提前声明 106 4.11 模块 107 4.12 类型 ID 109 4.13 Object 上的操作 110 4.14 本地类 111 4.15 Ice 模块 112 4.16 名字与作用域 113 4.17 元数据 117 4.18 使用 Slice 编译器 118 4.19 Slice 与 CORBA IDL 的对比 119 4.20 总结 127 第 5 章 一个简单文件系统的 Slice 定义 137 5.1 本章综 137 5.2 文件系统应用 137 5.3 文件系统的 Slice 定义 138 5.4 完整的定义 140 第 6 章 客户端的 Slice-to-C++ 映射 143 6.1 本章综 143 6.2 引言 143 6.3 标识符的映射 144 6.4 模块的映射 144 6.5 Ice 名字空间 145 6.6 简单内建类型的映射 146 6.7 用户定义类型的映射 146 6.8 常量的映射 150 6.9 异常的映射 151 6.10 运行时异常的映射 154 6.11 接口的映射 154 6.12 操作的映射 161 6.13 异常处理 167 6.14 类的映射 169 6.15 slice2cpp 命令行选项 183 6.16 与 CORBA C++映射比较 184 第 7 章开发 C++ 文件系统客户 189 7.1 本章综 189 7.2 C++ 客户 189 7.3 总结 194 第 8 章 客户端的 Slice-to-Java 映射 197 8.1 本章综 197 8.2 引言 197 8.3 标识符的映射 198 8.4 模块的映射 198 8.5 Ice Package 199 8.6 简单内建类型的映射 200 8.7 用户定义类型的映射 200 8.8 常量的映射 204 8.9 异常的映射 205 8.10 运行时异常的映射 206 8.11 接口的映射 207 8.12 操作的映射 213 8.13 异常处理 219 8.14 类的映射 220 8.15 Package 224 8.16 slice2java 命令行选项 225 第 9 章开发 Java 文件系统客户 229 9.1 本章综 229 9.2 Java 客户 229 9.3 总结 233 第 10 章 服务器端的 Slice-to-C++ 映射 235 10.1 本章综 235 10.2 引言 235 10.3 服务器端 main函数 236 10.4 接口的映射 247 10.5 参数传递 249 10.6 引发异常 251 10.7 对象体现 252 10.8 总结 257 第 11 章开发 C++ 文件系统服务器 261 11.1 本章综 261 11.2 实现文件系统服务器 261 11.3 总结 276 第 12 章 服务器端的 Slice-to-Java 映射 279 12.1 Chapter Overview 279 12.2 引言 279 12.3 服务器端 main函数 280 12.4 接口的映射 285 12.5 参数传递 287 12.6 引发异常 288 12.7 Tie 类 289 12.8 对象体现 292 12.9 总结 296 第 13 章开发 Java 文件系统服务器 297 13.1 本章综 297 13.2 实现文件系统服务器 297 13.3 总结 306 第 14 章 Ice 属性与配置 307 14.1 本章综 307 14.2 属性 307 14.3 配置文件 309 14.4 在命令行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值