强制转换:

(Cplusplus基础与提高(何桂林)21页)

static_cast:有隐式转换的

格式:

  1. static_cast<目标类型> (标识符)
  1. int a = 10;
  2. int b = 3;
  3. cout<<static_cast<float>(a)/b<<endl; //float = int int = float
  4. return 0;
  1. int *p; void *q;
  2. p = static_cast<int*>(q)

reinterpret_cast:没有隐式转换的

格式:

  1. reinterpret_cast<目标类型> (标识符)

举例:

  1. int main()
  2. {
  3.   int x = 0x12345648;
  4.   char *p = reinterpret_cast<char*>(&x);
  5.   //char*p = static_cast<char*>(&x);
  6.   printf("%x\n",*p);
  7.   int a[5] = {1,2,3,4,5};
  8.   int *q = reinterpret_cast<int*>((reinterpret_cast<int>(a) +1));
  9.   printf("%x\n",*q);
  10.   return 0;
  11. }

const_cast:脱常量的

格式:

  1. const_cast<目标类型> (标识符) //目标类类型只能是指针或引用。

举例:

  1. #include <iostream>
  2. using namespace std;
  3. void func(int & ref) //别人己经写好的程序或类库
  4. {
  5. cout<<ref<<endl;
  6. }
  7. int main(void)
  8. {
  9. const int m = 4444;
  10. func(const_cast<int&>(m));
  11. return 0;
  12. }

dynamic_cast(这个不需要)

容器:

Vector<String8> args;   (容器):

深入解析C++ STL中的常用容器

异常:

(Cplusplus基础与提高(何桂林)200页)

类模板:

1.类模板的定义: 
可用类模板来定义类,类模板是对象特性更为一般的抽象。简而言之,一个类模板就是一个抽象的类、类模板的一般定义形式为:

  1. template<参数名列表>
  2. class 类名{
  3. //类的说明
  4. };

其中,template是关键字,<参数名列表>中可以有多个参数,多个模板参数之间用逗号分隔。模板参数的形式可以是:

  1. class<标识符> 类型表达式<标识符>

如,可定义坐标点的类模板如下:

  1. template <class T> //带参数T的类模板说明
  2. class Point{
  3. public:
  4. Point(T = 0,T = 0); //类的构造函数
  5. Point(Point&); //类的复制构造函数
  6. T Distance(Point&); //返回类型为T的成员函数
  7. private:
  8. T x,y;
  9. };

2**.类模板的使用**: 
使用上述模板定义对象iobj,并以int替换参数T:

  1. Point<int> iobj(3,4); //该对象产生一个int型的点(3,4)

使用该模板再产生一个实例:

  1. Point<double>dobj(7.8,8.8); //该对象产生一个double型的坐标点(7.8,8.8)

由此可见,使用类模板可以声明不同类型的对象。对于一个可能用到多种数据类型的类来说,使用类模板可以大大提高编程的效率。简单地说,如果你需要int型的数据,就用int来替换参数模板中的T,需要double型的数据就用double来替换参数模板中的T。

以下代码给出了一个用类模板来描述坐标点的例子:

  1. #include<iostream>
  2. #include<cmath>
  3.  
  4. //The declaration of class template
  5. template<class T>
  6. class Point{
  7. public:
  8. Point(T = 0,T = 0);
  9. Point(Point&);
  10. T Distance(Point&);
  11. private:
  12. T x,y;
  13. };
  14.  
  15. //The implementation of class template Point
  16. template<class T>
  17. Point<T>::Point(T a,T b):x(a),y(b){}
  18.  
  19. template<class T>
  20. Point<T>::Point(Point& a)
  21. {
  22. x = a.x;
  23. y = a.y;
  24. }
  25.  
  26. template<class T>
  27. T Point<T>::Distance(Point& a)
  28. {
  29. return sqrt((x - a.x)*(x - a.x) + (y - a.y)*(y - a.y));
  30. }
  31.  
  32. //main function
  33. int main()
  34. {
  35. using namespace std; //Learn the meaning of "namespace" from 《C++ primer》
  36. Point<int>a1(3,4),a2(5,6);
  37. cout<<"The distance of these two points(int): "<<a1.Distance(a2)<<endl;
  38.  
  39. Point<double>b1(7.8,9.8),b2(34.8,25.4);
  40. cout<<"The distance of these two points(double): "<<b1.Distance(b2)<<endl;
  41. return 0;
  42. }

下图为运行结果:

显然,使用类模板能使得我们在处理需要多种数据类型的类时游刃有余,从上述程序中我们也很容易发现类模板与普通的类之间的差别。其实,只要去掉类模板的声明,并将T换成我们所需要的数据类型,再做些微小的改动就成为了一个普通的类。认识到这一点,对类模板的理解就会更加深刻。

 

智能指针

在Android的源代码中,经常会看到形如:sp<xxx>、wp<xxx>这样的类型定义,这其实是Android中的智能指针。智能指针是C++中的一个概念,通过基于引用计数的方法,解决对象的自动释放的问题。在C++编程中,有两个很让人头痛的问题:一是忘记释放动态申请的对象从而造成内存泄露;二是对象在一个地方释放后,又在别的地方被使用,从而引起内存访问错误。程序员往往需要花费很大精力进行精心设计,以避免这些问题的出现。在使用智能指针后,动态申请的内存将会被自动释放(有点类似Java的垃圾回收),不需要再使用delete来释放对象,也不需要考虑一个对象是否已经在其它地方被释放了,从而使程序编写工作减轻不少,而程序的稳定性大大提高。
Android的智能指针相关的源代码在下面两个文件中:
frameworks/base/include/utils/RefBase.h
frameworks/base/libs/utils/RefBase.cpp

Android中定义了两种智能指针类型,一种是强指针sp(strong pointer),一种是弱指针(weak pointer)。其实成为强引用和弱引用更合适一些。强指针与一般意义的智能指针概念相同,通过引用计数来记录有多少使用者在使用一个对象,如果所有使用者都放弃了对该对象的引用,则该对象将被自动销毁。
弱指针也指向一个对象,但是弱指针仅仅记录该对象的地址,不能通过弱指针来访问该对象,也就是说不能通过弱智真来调用对象的成员函数或访问对象的成员变量。要想访问弱指针所指向的对象,需首先将弱指针升级为强指针(通过wp类所提供的promote()方法)。弱指针所指向的对象是有可能在其它地方被销毁的,如果对象已经被销毁,wp的promote()方法将返回空指针,这样就能避免出现地址访问错的情况。
是不是很神奇?弱指针是怎么做到这一点的呢?其实说穿了一点也不复杂,原因就在于每一个可以被智能指针引用的对象都同时被附加了另外一个weakref_impl类型的对象,这个对象中负责记录对象的强指针引用计数和弱指针引用计数。这个对象是智能指针的实现内部使用的,智能指针的使用者看不到这个对象。弱指针操作的就是这个对象,只有当强引用计数和弱引用计数都为0时,这个对象才会被销毁。
说了这么多原理,下面该看看到底智能指针该怎么使用了。假设现在有一个类MyClass,如果要使用智能指针来引用这个类的对象,那么这个类需满足下列两个前提条件:
(1) 这个类是基类RefBase的子类或间接子类;
(2) 这个类必须定义虚构造函数,即它的构造函数需要这样定义:
virtual ~MyClass();
满足了上述条件的类就可以定义智能指针了,定义方法和普通指针类似。比如普通指针是这样定义:
MyClass* p_obj;
智能指针是这样定义:
sp<MyClass> p_obj;
注意不要定义成 sp<MyClass>* p_obj。初学者容易犯这种错误,这样实际上相当于定义了一个指针的指针。尽管在语法上没有问题,但是最好永远不要使用这样的定义。
定义了一个智能指针的变量,就可以象普通指针那样使用它,包括赋值、访问对象成员、作为函数的返回值、作为函数的参数等。比如:

  1. sp<MyClass> p_obj;
  2. p_obj = new MyClass(); // 注意不要写成 p_obj = new sp<MyClass>
  3. sp<MyClass> p_obj2 = p_obj;
  4. p_obj->func();
  5. p_obj = create_obj();
  6. some_func(p_obj);

注意不要试图delete一个智能指针,即 delete p_obj。不要担心对象的销毁问题,智能指针的最大作用就是自动销毁不再使用的对象。不需要再使用一个对象后,直接将指针赋值为NULL即可:
p_obj = NULL;
上面说的都是强指针,弱指针的定义方法和强指针类似,但是不能通过弱指针来访问对象的成员。下面是弱指针的示例:

  1. wp<MyClass> wp_obj = new MyClass();
  2. p_obj = wp_obj.promote(); // 升级为强指针。不过这里要用.而不是->,真是有负其指针之名啊
  3. wp_obj = NULL;

智能指针用起来是很方便,在一般情况下最好使用智能指针来代替普通指针。但是需要知道一个智能指针其实是一个对象,而不是一个真正的指针,因此其运行效率是远远比不上普通指针的。所以在对运行效率敏感的地方,最好还是不要使用智能指针为好。

基础语言知识C++的更多相关文章

  1. 基础语言知识JAVA

    1. 总结: JAVA比较重要的博客: http://www.runoob.com/java/java-tutorial.html     (JAVA教程) http://blog.csdn.net/ ...

  2. C#基础语言知识--编译和执行过程

    http://blog.csdn.net/stive_sourcexin/article/details/51329697

  3. C++基础语言知识大汇总(不断更新!!!)

    经过十天的时间,LITTLESUN做好了前期的工作,今天LITTLESUN就要在新地图里扬帆起航喽!!!(撒花) 简单的整理了一下这次启航准备好的物资.后面的航程中也会不断来补充这个小仓库哦!

  4. JAVA入门之基础语言

    在上一章文章中,读者已经了解了如何搭建Java 开发环境及Java 程序的开发过程.从本篇文章开始讲解Java 的基本语言.这些基本语言的语法和其他一些编程语言相比有些是类似的,但还有很多不同之处,读 ...

  5. 【转】R语言知识体系概览

    摘要:R语言的知识体系并非语法这么简单,如果都不了R的全貌,何谈学好R语言呢.本文将展示介绍R语言的知识体系结构,并告诉读者如何才能高效地学习R语言. 最近遇到很多的程序员都想转行到数据分析,于是就开 ...

  6. 『Python基础-1 』 编程语言Python的基础背景知识

    #『Python基础-1 』 编程语言Python的基础背景知识 目录: 1.编程语言 1.1 什么是编程语言 1.2 编程语言的种类 1.3 常见的编程语言 1.4 编译型语言和解释型语言的对比 2 ...

  7. Java基础语法知识你真的都会吗?

    第一阶段 JAVA基础知识 第二章 Java基础语法知识 在我们开始讲解程序之前,命名规范是我们不得不提的一个话题,虽说命名本应该是自由的,但是仍然有一定的"潜规则",通过你对命名 ...

  8. Web安全之Web 安全介绍与基础入门知识

    web安全介绍与基础入门知识 安全与安全圈 甲方与乙方 甲方:如腾讯,阿里等需要安全服务的公司 乙方:提供安全服务产品的服务型安全公司 web与二进制 web,研究web安全 二进制,研究如客户端安全 ...

  9. C语言知识汇总,史上最全面总结,没有之一

    C语言基础 C语言学习路线 C语言入门笔记 初识C语言 简单的C程序示例 我们编写的C代码是怎样跑起来的? 简单示例,VS2019调试C语言程序 C语言基础-数据类型 深入理解变量,变量的声明,定义, ...

随机推荐

  1. Visual Studio Code Angular4 配置环境

    首先在本机安装node.js才能用 npm 命令 环境搭建 安装node.jsnpm install -g @angular/cli 安装第三方库npm install --save bootstra ...

  2. asp.net mvc5 下载文件方法

    控制器自带的 FileContentResult 可以让我们很方便的返回文件到服务端,减少了很多步骤.用于下载文件的时候,像视频.文本.图片这种浏览器支持的文件,默认就会被浏览器打开.这时候想让它变成 ...

  3. visualstudio部分快捷键

    [工具快捷键] Ctrl+Shift+N: 新建项目 Ctrl+Shift+O: 打开项目 Ctrl+Shift+S: 全部保存 Shift+Alt+C: 新建类 Ctrl+Shift+A: 新建项 ...

  4. C++的一些知识点摘抄(创建基本类 高级类)

    问:对象有多大? 答:对象占据的内存量取决于其成员变量的长度,类函数不占据为对象分配的内容. 有些编译器在内存中对齐变量,这导致2字节变量实际占用的内存多于2字节. 问:为何不应将所有成员数据声明为公 ...

  5. .NET中的异常处理机制(一)

    1.异常处理的总体指导思想 学习C#中的异常处理机制,大概要了解以下几点: 首先,我们需要知道的事所有具体异常都是继承自System.Exception基类的. 其次,要熟悉FCL类库内置好的一些异常 ...

  6. RoadFlow ASP.NET Core工作流引擎IIS部署

    RoadFlow最新版本采用ASP.NET CORE2.1开发,部署步骤和.NET CORE部署一样,具体可参数ASP.NET CORE的部署方式. 1. 获取代码 首先从RoadFlow官网下载最新 ...

  7. JAVA—编码问题

    一.编码.(引用  百度百科) 编码是信息从一种形式或格式转换为另一种形式的过程也称为计算机编程语言的代码简称编码.用预先规定的方法将文字.数字或其它对象编成数码,或将信息.数据转换成规定的电脉冲信号 ...

  8. Visual Studio 2013的新特性介绍

    cnbeta新闻:微软正式发布Visual Studio 2013 RTM版,微软还发布了Visual Studio 2013的最终版本..NET 4.5.1以及Team Foundation Ser ...

  9. ASP.NET Core使用Ping判断网络是否接通

    static void Main(string[] args) { // 主机地址 string targetHost = "bing.com"; string data = &q ...

  10. 【Oracle 12c】CUUG OCP认证071考试原题解析(35)

    35.choose the best answer View the Exhibit and examine the description of the EMPLOYEES table. Evalu ...