Poco库学习——1

POCO


类型和字节顺序


固定大小整数类型

POCO定义固定大小的整数

#include "Poco/Types.h"

已经被自动包含到Poco/Foundation.h头文件中,含有

Poco::Int8,Poco::Int16,Poco::Int32,Poco::Int64

Poco::Uint8.Poco::UInt16,Poco::UInt32,Poco::UInt64

Poco::IntPtr,Poco::UIntPtr是和(32位或64位)系统指针相同大小的整数

内置类型的大小

POCO有两个宏定义来确定long类型和指针类型的大小

POCO_PTR_IS_64_BIT:如果指针为64位,则定义宏

POCO_LONG_IS_64_BIT:如果long型为64位,则定义宏

字节顺序

POCO 可以处理字节顺序问题

POCO有用于处理当前主机字节序的宏

  • POCO_ARCH_LITTLE_ENDIAN:小端的宏定义
  • POCO_ARCH_BIG_ENDIAN:大端的宏定义

类Poco::ByteOrder提供了字节顺序转换的静态方法

头文件:#include"Poco/ByteOrder.h"

IntXX flipBytes(IntXX value)

函数作用:将字节顺序从大端转为小端,反之亦然

字节顺序转换
IntXX toBigEndian(IntXX value)

函数作用:从主机字节序转化成大端序

IntXX toLittleEndian(IntXX value)

函数作用:从主机序转化成小端序

IntXX fromBigEndian(IntXX value)

函数作用:从大端序准转化成主机序

IntXX fromLittleEndian(IntXX value)

函数作用:从小端序转化为主机序

IntXX toNetwork(IntXX value)

函数作用:从本地字节序转化成网络字节序

IntXX fromNetwork(IntXX value)

函数作用:从网络字节序转化成本地字节序

网络字节序为大端序,以上方法均为内联方法

实例演示
#include "Poco/ByteOrder.h"
#include <iostream>
using Poco::ByteOrder;
using Poco::UInt16;
int main(int argc, char** argv)
{
#ifdef POCO_ARCH_LITTLE_ENDIAN
std::cout << "little endian" << std::endl;
#else
std::cout << "big endian" << std::endl;
#endif
UInt16 port = 80;
UInt16 networkPort = ByteOrder::toNetwork(port);
return 0;
}

任意类型(Any Type)

头文件:#include"Poco/Any.h"

作用:Poco::Any的值可以保存任何内置或者用户定义类型的值,且Poco::Any支持值语义,同时可以以类型安全的方式提取该值,为了提取它这个值必须已知

Poco::AnyCast()和Poco::RefAnyCast()函数模板用于提取值

#include "Poco/Any.h"
#include "Poco/Exception.h"
using Poco::Any;
using Poco::AnyCast;
using Poco::RefAnyCast;
int main(int argc, char** argv)
{
Any any(42);
int i = AnyCast<int>(any); // okay
int& ri = RefAnyCast<int>(any); // okay
try
{
short s = AnyCast<short>(any); // throws BadCastException
}
catch (Poco::BadCastException&)
{
}
return 0;
}

动态任意类型(The DynamicAny Type)

头文件:include"Poco/DynamicAny.h"

支持安全的隐式和显示转换为任何类型(标准类型,std::string)

DynamicAny - 转换规则
  1. 数字值不允许数据丢失精度
    • 值小于零永远不会转换为无符号类型
    • 如果需要x位的值,将永远不会转换为更小的位范围
  2. 允许int到float和back的精度丢失
  3. 允许字符串截断
#include "Poco/DynamicAny.h"
#include "Poco/Exception.h"
using Poco::DynamicAny;
int main(int argc, char** argv)
{
DynamicAny any(42);
int i = any;
std::string s(any.convert<std::string>());
 any.convert(s); // or without the need to cast
const int& ri(any.extract<int>());
short s = any;
try
{
short s = any.extract<short>(); // throws BadCastException
}
catch (Poco::BadCastException&)
{
}
return 0;
}

存储管理(Memory Management)


引用计数,共享指针,缓冲区管理等

引用计数

作用:每当一个引用被摧毁或者被重写,引用计数会减少

​ 每当一个引用被创建或者被复制,引用计数会增加

	  引用计数的初始值为1

​ 当引用计数为0时,会销毁对象

	  在多线程场景中,递增和递减/比较引用计数器必须是原子操作

对象所有权

拥有对象的所有权的对象也需要在不再需要这个对象时释放所有权

如果对象的拥有者没能释放这个对象,这将导致内存泄露

可能也会有其他指向该对象,但是他们永远不会删除对象

对象的所有权可以进行转让,但是同一时刻只有一个拥有对象所有权

引用计数和对象所有权

拥有引用计数所有权的指针不会增加引用计数

  • 这意味着没有以前的所有者(换句话说,对象刚刚被创建)
  • 或者之前的所有者放弃了所有权(因此没有减少对象的引用计数)

THE AUTOPTR CLASS TEMPLATE

Poco::AutoPtr实现了一个引用计数智能指针

任何支持引用计数的类都能支持Poco::AutoPtr的实例化

#include "Poco/AutoPtr.h"
using Poco::AutoPtr;
class RCO
{
public:
RCO(): _rc(1)
{
}
void duplicate()
{
++_rc; // Warning: not thread safe!
}
void release()
{
if (--_rc == 0) delete this; // Warning: not thread safe!
}
private:
int _rc;
};
int main(int argc, char** argv)
{
RCO* pNew = new RCO; // _rc == 1
AutoPtr<RCO> p1(pNew); // _rc == 1
AutoPtr<RCO> p2(p1); // _rc == 2
AutoPtr<RCO> p3(pNew, true); // _rc == 3
p2 = 0; // _rc == 2
p3 = 0; // _rc == 1
RCO* pRCO = p1; // _rc == 1
p1 = 0; // _rc == 0 -> deleted
// pRCO and pNew now invalid!
p1 = new RCO; // _rc == 1
return 0;
}
 // _rc == 0 -> deleted

AutoPtr 运算符和语义

Poco::AutoPtr支持关系运算符:==,!=,<,<=,>,>=

重定义了运算符:*,->

如果指针为空将会抛出NullPointerExcepttion如果指针为空

Poco::AutoPtr支持全值语义(默认构造函数,复制构造函数,赋值)可以在集合中使用

使用AutoPtr::isNull()或者AutoPtr::operator!()去测试空指针

AutoPtr和类型

和普通指针一样,Poco::AutoPtr支持强制类型转换

#include "Poco/AutoPtr.h"
#include "Poco/RefCountedObject.h"
class A: public Poco::RefCountedObject {};
class B: public A {};
class C: public Poco::RefCountedObject {};
int main(int argc, char** argv)
{
Poco::AutoPtr<A> pA;
Poco::AutoPtr<B> pB(new B);
pA = pB; // okay, pB is a subclass of pA
pA = new B;
// pB = pA; // will not compile
pB = pA.cast<B>(); // okay
Poco::AutoPtr<C> pC(new C);
pA = pC.cast<A>(); // pA is null
return 0;
}

AutoPtr注意事项和陷阱

将AutoPtr指定给普通指针,然后将普通指针指定给另一个AutoPtrs时,请格外小心!

两个指针都会声明对对象的所有权

#include "Poco/AutoPtr.h"
#include "Poco/RefCountedObject.h"
class A: public Poco::RefCountedObject
{
};
int main(int argc, char** argv)
{
Poco::AutoPtr<A> p1(new A);
A* pA = p1;
// Poco::AutoPtr<A> p2(pA); // BAD! p2 assumes sole ownership
Poco::AutoPtr<A> p2(pA, true); // Okay: p2 shares ownership with p1
Poco::AutoPtr<A> p3;
// p3 = pA; // BAD! p3 assumes sole ownership
p3.assign(pA, true); // Okay: p3 shares ownership with p1
return 0;
}

AutoRealsePool

Poco::AutoRealsePool负责类模板负责(引用计数)其他人不需要的对象

头文件:#include"Poco/AutoReleasePool.h"

Poco::AutoReleasePool拥有所有添加到它的每个对象的所有权

当Poco::AutoReleasePool被摧毁时,释放所有对象的引用,通过调用Release()方法

#include "Poco/AutoReleasePool.h"
using Poco::AutoReleasePool;
class C
{
public:
C()
{
}
void release()
{
delete this;
}
};
int main(int argc, char** argv)
{
AutoReleasePool<C> pool;
C* pC = new C;
pool.add(pC);
pC = new C;
pool.add(pC);
return 0;
}
// all C's deleted

SharedPtr

Poco::SharedPtr为本身没有实现引用计数的类实现应用计数

头文件:#include"Poco/SharedPtr.h"

警告

将指向同一对象的普通指针分配给不同的SharedPtr将导致对象的多个所有者发生为定义的行为(换句话说,将会崩溃)

一旦将SharedPtr用于对象,就不要再使用指向该对象的普通指针

#include "Poco/SharedPtr.h"
#include <string>
#include <iostream>
using Poco::SharedPtr;
int main(int argc, char** argv)
{
std::string* pString = new std::string("hello, world!");
Poco::SharedPtr<std::string> p1(pString); // rc == 1
Poco::SharedPtr<std::string> p2(p1); // rc == 2
p2 = 0; // rc == 1
// p2 = pString; // BAD BAD BAD: multiple owners -> multiple delete
p2 = p1; // rc == 2
std::string::size_type len = p1->length(); // dereferencing with ->
std::cout << *p1 << std::endl; // dereferencing with *
return 0;
}
// rc == 0 -> deleted

动态工厂类模板(The DynamicFactory Class Template)

Poco::DynamicFactory支持按“名称”创建对象

头文件:#include “Poco/DynamicFactory.h”

DynamicFactory管理的所有类都必须有公共的基类,DynamicFactory为基类进行实例化

C* DynamicFactory::createInstance(const std::string& name)const;

创建一个拥有给出名字的C子类的实例

类及其实例化类(工厂类)必须向DynamicFactory进行注册

Poco::Instantiator是给定类的工厂模板

定义了一个方法createInstance(),该方法创建一个新的类的实例,使用new运算符

为了使用类层次结构,实例化程序总是继承自Poco::AbstractInstantiator,后者为基类定义了createInstance()

#include "Poco/DynamicFactory.h"
#include "Poco/SharedPtr.h"
using Poco::DynamicFactory;
using Poco::SharedPtr;
class Base
{
};
class A: public Base
{
};
class B: public Base
{
};
int main(int argc, char** argv)
{
DynamicFactory<Base> factory;
factory.registerClass<A>("A"); // creates Instantiator<A, Base>
factory.registerClass<B>("B"); // creates Instantiator<B, Base>
SharedPtr<Base> pA = factory.createInstance("A");
SharedPtr<Base> pB = factory.createInstance("B");
// you can unregister classes
factory.unregisterClass("B");
// you can also check for the existence of a class
bool haveA = factory.isClass("A"); // true
bool haveB = factory.isClass("B"); // false (unregistered)
bool haveC = factory.isClass("C"); // false (never registered)
return 0;
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值