`
evasiu
  • 浏览: 168970 次
  • 性别: Icon_minigender_2
  • 来自: 广州
博客专栏
Fa47b089-e026-399c-b770-017349f619d5
TCP/IP详解卷一>阅读...
浏览量:12524
社区版块
存档分类
最新评论

C++ premier -- 内存管理与RTTI

 
阅读更多

第18章对于没有多少项目经验的我来说有些东西还真的是不知道实际应该如何应用,这些都涉及设计吧我想。看完这一篇,体会比较深的是内存管理和运行时类型识别,其他的包括类成员指针、嵌套类、局部类、联合等,看完只能说,知道了有这么回事,呵呵。

创建对象一般涉及两个过程,一是分配内存,然后构造对象,这两者相互纠缠在一起,就像对象析构和回收内存一样。构造对象指的是运行构造函数,包括对数据成员进行赋值;析构对象指的是运行析构函数,包括释放构造对象时动态请求的资源。C++中提供了两种方法来完成这些事情:
1. 使用allocator类。
allocator类是一个模板,它提供类型化的内存分配以及对象构造与撤销,下面是该类支持的操作:



 Vector类的实现把里面的操作基本都用上了:

#include<memory>

template <class T> class Vector{
	public:
		Vector():elements(0),first_free(0),end(0){};
		void push_back( const T& );
	private:
		static std::allocator<T> alloc;
		void reallocate();
		T* elements;
		T* first_free;
		T* end;
	};

template<class T> std::allocator<T> Vector<T>::alloc;

template<class T> void Vector<T>::push_back( const T& t ){
	if( first_free == end )
		reallocate();
	alloc.construct(first_free, t );
	++first_free;
}

template<class T> void Vector<T>::reallocate(){
	std::ptrdiff_t size = first_free - elements;
	std::ptrdiff_t newcapacity = size>0? 2*size : 2;
	T* newelements = alloc.allocate(newcapacity);
	
	std::uninitialized_copy(elements, first_free, newelements);
	for( T* p=first_free; p != elements; )
		alloc.destroy( --p );
	
	if( elements )
		alloc.deallocate(elements, end-elements);
	
	elements = newelements;
	first_free = elements +size;
	end = elements+newcapacity;
}

 
2. new、delete表达式
当使用new表达式 string *sp = new string( "hello world" ); 的时候,实际上发生三个步骤:
 首先,该表达式调用名为operator new的标准库函数,分配足够大的原始的未类型化的内存,以保存指定类型的一个对象;
 接着,运行该类型的一个构造函数,用指定初始化式构造对象;
 最后,返回指向新分配并构造的对象的指针,但指针类型为void*。
标准库中的operator new和operator delete,它们分配和释放需要大小的原始的、未类型化的内存。
同样,当使用delete表达式 delete sp的时候,实际上也发生了两个步骤:
 首先,对sp指向的对象运行适当的析构函数
 接着,通过调用名为operator delete的标准函数释放该对象所用的内存。
operator new和operator delete函数有两个重载版本,每个版本支持相关的new表达式和delete表达式:

 void* operator new(size_t);
 void* operator new[](size_t);
 
 void operator delete( void* );
 void operator delete[]( void* );

事实上,还有第三种new表达式,称为定位new(placement new),其形式如下:

new (place_address) type
new (place_address) type( initialized_list );

如alloc.construct( first_free, t );可以改写成:
new (first_free) T(t);
定义new表达式比allocator类的construct成员更灵活,它可以使用任何构造函数并直接建立对象,而construct函数总是使用复制构造函数。
可以用下面两种方式之一,从一对迭代器初始化一个已分配但未构造的string对象:
allocator<string>* alloc;
string* sp = alloc.allocate(2);
new (sp) string(b,e);  //construct directly in place
alloc.construct( sp+1, string(b,e) );  //build and copy a temporary

通过运行时类型识别(RTTI),程序能够使用基类的指针或引用来检查这些指针或引用所指对象的实际派生类型,有两种操作:
1. typeid操作符,返回指针或引用所指对象的实际类型
2. dynamic_cast操作符,将基类类型的指针或引用安全地转换为派生类型的指针或引用
这些操作符只为带有一个或多个虚函数的类返回动态类型信息,对于其他类型,返回静态类型的信息。
dynamic_cast操作符一次执行两个操作,它首先验证被请求的转换是否有效,只有转换有效,操作符才实际进行转换。
假设Base是至少带有一个虚函数的类,并且Derived类派生于Base类,basePtr为指向Base的指针,就可以像这样在运行时将它强制转换为指向Derived的指针:

if( Derive * derivePtr = dynamic_cast<Derived*>(basePtr) ){ //如果指针转换失败,derivedPtr=0;
	//use Derived object to which derivedPtr points
}else{
	//use the Base object to which basePtr points
}

如果引用转换失败,dynamic_cast抛出bad_cast异常

void f( const Base& b ){
	try{
		const Derived& d = dynamic_cast<const Derived&>(b);
		//use Derived object to which derivedPtr points
	}catch( bad_cast ){
		//use the Base object to which basePtr points
	}

typeid要注意的是,typeid的操作数是表示对象的表达式,对于指针,返回的类型是是“指向<静态类型>的指针”

后面的内容就不总结了,我觉得没有一定的项目经验,那些东西的好处其实也是无法体会的,呵呵。

  • 大小: 69.1 KB
分享到:
评论

相关推荐

    C++premier 第四版中文版

    根据提供的信息,我们可以推断出这是一段与C++编程语言相关的教材内容。尽管原文包含大量乱码,但我们可以从可识别的部分出发,提取并解释关键知识点。 ### 标题和描述中的知识点 #### C++ Premier 第四版中文版 ...

    CPP-Premier-Plus.zip_plus_销售

    《C++ Primer Plus》是一本深受程序员喜爱的C++...总的来说,"CPP-Premier-Plus.zip_plus_销售"包含的资源是C++初学者和教育者的宝贵工具,它们有助于深化理论学习,提高实践能力,并可能推动相关课程的推广与销售。

    c++ premier 习题解答(完整pdf版)

    c++ premier 是学习c++的经典著作,通过学习这本数,你可以有很大进步;本资源是书本对应的习题解答,第四版,相当详细

    C++ premier中文版 电子书

    2. **面向对象编程**:C++的核心在于其面向对象特性,包括类的设计、对象的创建与使用、封装、继承和多态性。这些概念使得C++能够构建复杂、模块化的软件系统。 3. **模板**:C++的模板机制允许开发者编写泛型代码...

    2017-NESC-handbook-premier-edition.zip

    《2017-NESC-handbook-premier-edition.zip》是一个包含2017年北美电气规范(National Electrical Safety Code, 简称NESC)首版手册的压缩文件。NESC是美国和加拿大广泛使用的电力设施安装、维护和操作的安全标准。...

    Premier - MS Windows Shell Script Programming for the Absolute Beginner.chm

    Premier - MS Windows Shell Script Programming for the Absolute Beginner.chm

    C++ Premier第四版中文英文源代码

    3. **类与对象**:C++的核心是面向对象编程,类是对象的蓝图,而对象则是类的实例。书中将详细讲解如何定义类,包括成员变量和成员函数,以及构造函数和析构函数的作用。此外,还将探讨访问修饰符(public、private...

    c++ premier 第四版 课后习题答案+所有源代码

    通过阅读和运行这些代码,读者可以更直观地理解C++的各种特性,如类的设计与实现、模板的使用、异常处理、输入输出流等。同时,这些源代码也展示了良好的编程习惯和风格,对于培养编程思维和提升代码质量有着积极的...

    Premier - Crystal Reports 9 Essentials_crystalreports9_crystalre

    《Premier - Crystal Reports 9 Essentials》是一本深入解析Crystal Reports 9这一强大报表工具的教程,旨在帮助用户掌握其核心功能与应用技巧。Crystal Reports是Business Objects公司(现为SAP的一部分)开发的一...

    premier-eye:物体检测程序

    总理眼物体检测程序 开始工作之前,Premier-eye需要在设备上创建数据和输出文件夹,并将图像放置在此处以进行识别工作。物体检测模块当地使用要求: Python&gt; = 3.6 对于运行模块,您需要运行API和SPA来发送数据,...

    ebs-122-premier-support-extended-through-at-least-2035.pdf

    oracle ebs

    C++ Premier 中英文对照chm版

    6. **内存管理**:C++允许程序员直接管理内存,包括动态分配和释放,但这也要求程序员有良好的内存管理意识,以防止内存泄漏和悬挂指针等问题。 7. **输入/输出流**:C++的I/O流库(iostream)提供了用户友好的方式...

    C++ Premier 第一章思维导图学习

    XMind是一个非常神奇的软件,能够帮助我们组织思考,很不错的工具。C++ Premier是非常成熟的开发语言讲解书籍,非常经典

    C++ Premier顺序容器思维导图总结

    附件的内容为使用思维导图XMind总结C++标准库的顺序容器,通过把C++ Premier顺序容器翔实的放在一张图片上,可以非常方便的梳理思路,在工作中也能提高工作效率。灵活的使用容器是C++开发人员必须具备的技能

Global site tag (gtag.js) - Google Analytics