精华内容
下载资源
问答
  • PASCAL VOC数据集分析(分类部分

    万次阅读 2017-12-05 14:24:50
    Layout下存放的是具有人体部位的数据(人的head、hand、feet等等,这也是VOC challenge的一部分) Main下存放的是图像物体识别的数据,总共分为20。 Segmentation下存放的是可用于分割的数据。 ...

    PASCAL VOC数据集分析
    PASCAL VOC为图像识别和分类提供了一整套标准化的优秀的数据集,从2005年到2012年每年都会举行一场图像识别challenge。
    每一年都有自己的数据集。pascal_voc_2012网址:http://cvlab.postech.ac.kr/~mooyeol/pascal_voc_2012/

    VOC2005:包括训练集,验证集,测试集。只有4类,bicycles, cars, motorbikes, people. 
    Train/validation/test: 1578 images containing 2209 annotated objects.
    VOC2006:包括训练集,验证集,测试集。扩充到10类, bicycle, bus, car, cat, cow, dog, horse, motorbike, person, sheep.
    Train/validation/test: 2618 images containing 4754 annotated objects.
    VOC2007:包括训练集,验证集,测试集。扩充到20类,
    • Person: person
    • Animal: bird, cat, cow, dog, horse, sheep
    • Vehicle: aeroplane, bicycle, boat, bus, car, motorbike, train
    • Indoor: bottle, chair, dining table, potted plant, sofa, tv/monitor
    Train/validation/test: 9,963 images containing 24,640 annotated objects.

    2007年之后,VOV数据集不再提供测试集的标签信息,Instead, results on the test data are submitted to an evaluation server.算法在测试集上的结果被提交到服务器上进行在线验证。
    VOC201220 classes. The train/val data has 11,530 images containing 27,450 ROI annotated objects and 6,929 segmentations.

    人类;
    动物(鸟、猫、牛、狗、马、羊);
    交通工具(飞机、自行车、船、公共汽车、小轿车、摩托车、火车);
    室内(瓶子、椅子、餐桌、盆栽植物、沙发、电视)


    本文主要分析PASCAL VOC数据集中和图像中物体识别相关的内容。
    在这里采用PASCAL VOC2012作为例子。下载地址为:点击打开链接。(本文中的系统环境为ubuntu14.04)
    下载完之后解压,可以在VOCdevkit目录下的VOC2012中看到如下的文件:

    其中在图像物体识别上着重需要了解的是Annotations、ImageSets和JPEGImages。

    JPEGImages
    JPEGImages文件夹中包含了PASCAL VOC所提供的所有的图片信息,包括了训练图片和测试图片。
    这些图像都是以“年份_编号.jpg”格式命名的。
    图片的像素尺寸大小不一,但是横向图的尺寸大约在500*375左右,纵向图的尺寸大约在375*500左右,基本不会偏差超过100。(在之后的训练中,第一步就是将这些图片都resize到300*300或是500*500,所有原始图片不能离这个标准过远。)
    这些图像就是用来进行训练和测试验证的图像数据。

    Annotations

    Annotations文件夹中存放的是xml格式的标签文件,每一个xml文件都对应于JPEGImages文件夹中的一张图片。
    xml文件的具体格式如下:(对于2007_000392.jpg)
    [html]  view plain  copy
    1. <annotation>  
    2.     <folder>VOC2012</folder>                             
    3.     <filename>2007_000392.jpg</filename>                               //文件名  
    4.     <source>                                                           //图像来源(不重要)  
    5.         <database>The VOC2007 Database</database>  
    6.         <annotation>PASCAL VOC2007</annotation>  
    7.         <image>flickr</image>  
    8.     </source>  
    9.     <size>                                               //图像尺寸(长宽以及通道数)                        
    10.         <width>500</width>  
    11.         <height>332</height>  
    12.         <depth>3</depth>  
    13.     </size>  
    14.     <segmented>1</segmented>                                   //是否用于分割(在图像物体识别中01无所谓)  
    15.     <object>                                                           //检测到的物体  
    16.         <name>horse</name>                                         //物体类别  
    17.         <pose>Right</pose>                                         //拍摄角度  
    18.         <truncated>0</truncated>                                   //是否被截断(0表示完整)  
    19.         <difficult>0</difficult>                                   //目标是否难以识别(0表示容易识别)  
    20.         <bndbox>                                                   //bounding-box(包含左下角和右上角xy坐标)  
    21.             <xmin>100</xmin>  
    22.             <ymin>96</ymin>  
    23.             <xmax>355</xmax>  
    24.             <ymax>324</ymax>  
    25.         </bndbox>  
    26.     </object>  
    27.     <object>                                                           //检测到多个物体  
    28.         <name>person</name>  
    29.         <pose>Unspecified</pose>  
    30.         <truncated>0</truncated>  
    31.         <difficult>0</difficult>  
    32.         <bndbox>  
    33.             <xmin>198</xmin>  
    34.             <ymin>58</ymin>  
    35.             <xmax>286</xmax>  
    36.             <ymax>197</ymax>  
    37.         </bndbox>  
    38.     </object>  
    39. </annotation>  
    对应的图片为:
    ImageSets

    ImageSets存放的是每一种类型的challenge对应的图像数据。
    在ImageSets下有四个文件夹:
    其中Action下存放的是人的动作(例如running、jumping等等,这也是VOC challenge的一部分)
    Layout下存放的是具有人体部位的数据(人的head、hand、feet等等,这也是VOC challenge的一部分)
    Main下存放的是图像物体识别的数据,总共分为20类。
    Segmentation下存放的是可用于分割的数据。

    在这里主要考察Main文件夹。
    Main文件夹下包含了20个分类的***_train.txt、***_val.txt和***_trainval.txt。
    这些txt中的内容都差不多如下:
    前面的表示图像的name,后面的1代表正样本,-1代表负样本。
    _train中存放的是训练使用的数据,每一个class的train数据都有5717个。
    _val中存放的是验证结果使用的数据,每一个class的val数据都有5823个。
    _trainval将上面两个进行了合并,每一个class有11540个。
    需要保证的是train和val两者没有交集,也就是训练数据和验证数据不能有重复,在选取训练数据的时候 ,也应该是随机产生的。
    SegmentationClass和SegmentationObject

    这两个文件夹下保存了物体分割后的图片,在物体识别中没有用到,在这里不做详细展开。

    VOC2007数据集共包含:训练集(5011幅),测试集(4952幅),共计9963幅图,共包含20个种类。

    数据集的组成架构如下:

    • Annotations —目标真值区域
    • ImageSets —-类别标签
    • JPEGImages —–图像
    • SegmentationClass
    • SegmentationObjec

      JPEGImages 中存放原始图像,jpg格式。大小一般为 500*375 或 375*500; 
      ImageSets 中有三个文件夹【Layout】【Main】【Segmentation】,分类识别我们只关注【Main】,它内部存储类别标签,-1表示负样本,+1为正样本 
      *_train.txt 训练样本集 
      *_val.txt 评估样本集 
      *_trainval.txt 训练与评估样本汇总

      2 各类别统计信息

      20个类别中,后面数字代表数据集中对应的的正样本图像个数(非目标个数)。

      - 训练集

      aeroplane 238 
      bicycle 243 
      bird 330 
      boat 181 
      bottle 244 
      bus 186 
      car 713 
      cat 337 
      chair 445 
      cow 141 
      diningtable 200 
      dog 421 
      horse 287 
      motorbike 245 
      person 2008 
      pottedplant 245 
      sheep 96 
      sofa 229 
      train 261 
      tvmonitor 256

      - 测试集

      aeroplane 204 
      bicycle 239 
      bird 282 
      boat 172 
      bottle 212 
      bus 174 
      car 721 
      cat 322 
      chair 417 
      cow 127 
      diningtable 190 
      dog 418 
      horse 274 
      motorbike 222 
      person 2007 
      pottedplant 224 
      sheep 97 
      sofa 223 
      train 259 
      tvmonitor 229

      可以看出,除了person数量较多,其他类别样本个数不算多。

      因此,用VOC数据来训练模型,做行人检测或者车辆检测,数据是不够的,需要自己扩充数据。


      转载自:http://blog.csdn.net/zhangjunbob/article/details/52769381
      展开全文
    • 一.的基本定义语法,使用关键字class去定义一个,语法格式如下:访问控制符 class 类名{  成员变量声明  构造器声明  成员方法声明 ...花括号内为的主体,类体中一般包括3个部分,成员变量...

      一.类的基本定义语法使用关键字class去定义一个类,语法格式如下:访问控制符 class 类名{

                   成员变量声明

                   构造器声明

                  成员方法声明

      }

      一.访问控制符 包含:public ,private ,protected

      二.类名要有意义,且首字母大写

      三.花括号内为类的主体,类体中一般包括3个部分,成员变量声明,成员方法声明和构造器声明。

      二.Java自定义一个类的步骤如下:

      1.用关键字class定义类(考虑修饰符和类名)

      2.编写类的属性 ( 属性即成员变量)

      3.编写类的构造器(构造方法)

      4.编写类的方法(成员方法,考虑修饰符,返回值类型,方法名和)

      二.构造方法    的定义语法格式如下:

      访问控制符 构造方法名 ([参数列表])[throws 子句(Exception)]{

                     方法体

      }

      1.构造方法名必须和类名相同,注意大小写

      2.通常使用访问控制符为public

      3.构造方法可以不带参数,也可以带多个参数

      4.构造方法不显示返回类型,也不能使用void声明

      三.成员变量 基本格式和要求如下:

      访问修饰符 修饰符 类型 属性名称=初始值;

      1.访问修饰符:可以使用四种不同的访问修饰符中的一种,包括public(公共的)、protected(受保护的),无修饰符和 private(私有的)。public 访问修饰符表示属性可以从任何其它代码调用。private 表示属性只可以由该类中的其它方法来调用。protected 将在以后的课程中讨论。

      2.修饰符:是对属性特性的描述,例如后面会学习到的:static、final 等等。

      3.类型:属性的数据类型,可以是任意的类型。

      4.属性名称:任何合法标识符

      5.初始值:赋值给属性的初始值。如果不设置,那么会自动进行初始化,基本类型使用缺省值,对象类型自动初始化为 null。

      三.成员方法 基本格式和要求如下:

      访问修饰符 修饰符 返回值类型 方法名称 (参数列表) throws 异常列表 {方法体}

      1.返回值类型:表示方法返回值的类型。如果方法不返回任何值,它必须声明为 void(空)。Java 技术对返回值是很严格的,例如,如果声明某方法返回一个int值,那么方法必须从所有可能的返回路径中返回一个int值(只能在等待返回该 int 值的上下文中被调用。)

      2.方法名称:可以是任何合法标识符,并带有用已经使用的名称为基础的某些限制条件。

      3.参数列表:允许将参数值传递到方法中。列举的元素由逗号分开,而每一个元素包含一个类型和一个标识符。在下面的方法中只有一个形式参数,用 int 类型和标识符 days 来声明:
      public void test(int days){}

      4.throws 异常列表:子句导致一个运行时错误(异常)被报告到调用的方法中,以便以合适的方式处理它。异常在后面的课程中介绍。

      • 花括号内是方法体,即方法的具体语句序列
      展开全文
    • http 请求包含哪几个部分(请求行、请求头、请求) http协议报文 1.请求报文(请求行/请求头/请求数据/空行) 请求行 求方法字段、URL字段和HTTP协议版本 例如:GET /index.html HTTP/1.1 get方法将数据拼接在url...

      http 请求包含哪几个部分(请求行、请求头、请求体)

      http协议报文
      1.请求报文(请求行/请求头/请求数据/空行)

      请求行
      求方法字段、URL字段和HTTP协议版本
      例如:GET /index.html HTTP/1.1
      get方法将数据拼接在url后面,传递参数受限
      请求方法:
      GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT
      请求头(key value形式)
      User-Agent:产生请求的浏览器类型。
      Accept:客户端可识别的内容类型列表。
      Host:主机地址
      请求数据
      post方法中,会把数据以key value形式发送请求
      空行
      发送回车符和换行符,通知服务器以下不再有请求头
      2.响应报文(状态行、消息报头、响应正文)
      状态行
      消息报头
      响应正文

      例如请求数据:

      1 GET/sample.jspHTTP/1.1
      2 Accept:image/gif.image/jpeg,/
      3 Accept-Language:zh-cn
      4 Connection:Keep-Alive
      5 Host:localhost
      6 User-Agent:Mozila/4.0(compatible;MSIE5.01;Window NT5.0)
      7 Accept-Encoding:gzip,deflate
      8
      9 username=jinqiao&password=1234

      第一行为http请求行,包含方法,URI 和http版本
      2-7为请求头,包含浏览器,主机,接受的编码方式和压缩方式
      第8行表示一个空行 表示请求头结束 这个空行是必须的
      第9行是数据体,比如是需要查询的信息。
      http响应体由三部分组成:
      http响应由三个部分组成分别是状态行,响应头,响应正文。
      状态行是由:HTTP-Version+Status-Code+Reason-Phrase
      比如:HTTP/1.1 200 ok
      分别表示http版本 + 状态码 + 状态代码的文本描述
      状态码:

      1xx:
      指示信息–表示请求已接收,继续处理
      2xx:
      成功–表示请求已被成功接收、理解、接受
      3xx:
      重定向–要完成请求必须进行更进一步的操作。
      4xx:
      客户端错误–请求有语法错误或请求无法实现。
      5xx:
      服务器端错误–服务器未能实现合法的请求。

      响应头:包含服务器类型,日期,长度,内容类型等
      Server:Apache Tomcat/5.0.12
      Date:Mon,6Oct2003 13:13:33 GMT
      Content-Type:text/html
      Last-Moified:Mon,6 Oct 2003 13:23:42 GMT
      Content-Length:112
      响应正文响应正文就是服务器返回的HTML页面或者json数据

      @ cc

      展开全文
    • C++的介绍

      万次阅读 多人点赞 2018-02-09 16:11:57
      (其中部分官方定义和程序设计方法来源于西北工业大学魏英老师)1.的定义:是用户自定义的数据类型。C++一个定义的形式如下:class 类名{ 成员列表};成员列表是成员的集合,数目可以任意多, 一对 { } 是成员...

      最近在学习SLAM,顺便将C++类的知识复习一下。(其中部分官方定义和程序设计方法来源于西北工业大学魏英老师)

       

      1.类的定义:

      是用户自定义的数据类型。
      C++一个类定义的形式如下:
      class 类名 
      {
              成员列表
      };
      成员列表是类成员的集合,数目可以任意多, 一对 { } 是成员列表边界符,与成员列表一起成为类体。类体后面必须用 ; 结束。
      1.每个类可以没有成员,也可以有多个成员。
      2.类成员可以是数据或函数。
      3.所有成员必须在类内部声明,一旦类定义完成后,就没有任何其他方式可以再增加或减少成员。
       
      在面向对象程序设计中,一般将变量(数据)隐蔽起来,外部不能直接访问。把成员函数作为对外界的接口,通过成员函数访问数据,可能一开始学习的时候不太理解,这个我们在后面会经常用到,请耐心观看。
       
      类中如果有成员函数,则声明是必须的,而定义是可选的,什么意思呢,请看下例:
       
      在类内部定义函数体
      class 类名
      {
               返回类型   函数名(形参列表)
               {
                        函数体
               }
      };
       
      在类外部定义函数体
      class 类名
      {
               返回类型   函数名(形参列表);
      };
      返回类型   类名 :: 函数名(形参列表)
               函数体
       
      看到这里会产生一个问题,那就是这两种定义方法到底有什么区别,或者根本没有区别。
      其实它们还是有区别的,类内部定义的函数,程序在要调用它的时候会把它当作是一个内联函数,内联函数的好处是调用速度更快,但是会占用额外的内存空间,每调用一次都相当于定义一次。而外部定义的函数,就不会被当作内联函数。对于一些要用到递归的函数,定义成内联函数肯定是不合理的。因此建议使用第二种方法定义成员函数。
       
      类的定义一般放在程序文件开头,或者放到头文件中被程序文件包含,当然也可以放在局部作用域里。这里有必要提一下,c++规定,在局部作用域中声明的类,成员函数必须是函数定义形式,不能是原型声明。
       
      类相当于一种新的数据类型,数据类型不占用存储空间,用类型定义一个实体的时候,才会为它分配存储空间。
       
       

      2.类成员的访问控制:

      对类的成员进行访问,有两个访问源:类成员和类用户。
      类成员指类本身的成员函数,类用户指类外部的使用者,包括全局函数,另一个类的成员函数等。
      在C++中,类的每个成员都有访问控制属性:public(公有的)、private(私有的)、protected(保护的)
      类用户想要访问类的数据成员,必须通过公有成员访问。
      上面说过,面向对象程序设计过程中一般将数据隐蔽起来,也就是说一般的变量(数据)都声明为private,而成员函数声明为public,protected在后面我们会用到,不考虑继承的话,和private的性质一致。如果在声明的时候不写访问控制属性,则类会默认它为private。
       
      在刚才类定义的基础上进行扩展:
      class 类名
      {
      public:
           公有的数据成员和成员函数
      protected:
           保护的数据成员和成员函数
      private:
           私有的数据成员和成员函数
      };
       
      类的成员函数和普通函数一样,也可以进行重载,设置默认参数,显式的指定为内联函数等。
      这里有个小问题,请看下例:
      class Test
      {
      public:
          void Sum(int a=0,int b=0);
      };
      void Test::Sum(int a=0,int b=0)
      {
          cout<<a+b;
      }
      这是一个设置了默认参数的函数,但是很遗憾,这是错误的,下面这样则是正确的:
      class Test
      {
      public:
          void Sum(int a=0,int b=0);
      };
      void Test::Sum(int a,int b)
      {
          cout<<a+b;
      }
      原因是C++中对于特定的某个函数,设置默认形参这个动作只能有一次
       
       

      3.对象的定义和使用:

      说了这么多,怎么样才能实现在外部实现对类成员的访问呢?这就是我们要讨论的对象。
       
      对类的定义就是定义了一个具体的数据类型,要使用它必须将类实例化,即定义该类的对象。
      以下两种定义类对象的方法都是合法的(假定有一个Test类):
      Test test1 , test2;
      class Test test1 , test2;
      之前说过,定义类型时不会分配存储空间,当定义一个对象的时候,将为其分配存储空间。
       
      当然,有时候人们也希望可以动态的为其分配内存,当不用的时候再销毁它,就有了如下定义方式:
      Test *p;
      p = new Test;
      当不再使用此动态对象的时候,必须用delete:
      delete p;
      现在关心的应该是怎么通过对象调用类的成员?
      访问对象中的成员有三种方法:
      通过对象名和对象成员引用运算符 (.) 
      通过指向对象的指针和指针成员引用运算符 (->)
      通过对象的引用变量和对象成员引用运算符 (.) 
       
       
      假定有一个Test类,类中有一个 公有的Sum()函数,则在外部调用Sum()的方法有:
      Test test;
      test.Sum();
       
      Test *p;
      p = new Test;
      p->Sum();

      Test test, &r = test;
      r.Sum();
      这些方式都是合法的。
       
       
       

      4.构造函数与析构函数:

      建立一个对象的时候,通常最需要做的工作就是初始化对象,如对数据成员赋初值,而构造函数就是用来在创建对象时初始化对象,为对象数据成员赋初值。为什么非得这么做呢?因为在类里面,数据成员不能够进行初始化。即:
      class  Test
      {
           int x = 0;
           ...
      };
      这样做是错误的。
      想想为什么不可以,还是上面说过的,类只是定义了一个数据类型,不会占用存储空间,而在类里面对数据成员赋初值则会占用存储空间,因此自相矛盾。
       
      如果数据成员是公有的,那么可以在类外直接对它初始化,但如果是私有的,那么就不能直接访问它,这就要用到构造函数。构造函数就是用来处理对象的初始化问题,构造函数是一种特殊的成员函数,不需要人为调用,而是在对象建立的时候自动被执行。
       
      C++规定构造函数的名字要与类名保持一致,而且不能指定返回类型。请看下面程序:
      #include <iostream>
      
      using namespace std;
      
      class Test
      {
      public:
          Test ();
          Test (int x,int y);
          void Sum();
      private:
          int a,b;
      };
      Test::Test()
      {
      
      }
      Test::Test(int x,int y)
      {
          a=x;
          b=y;
      }
      void Test::Sum()
      {
          cout<<a+b;
      }
      int main()
      {
          Test test(3,4);
          test.Sum();
          return 0;
      }
      
      这里定义了两个构造函数 Test() 和 Test(int x,int y),由于创建对象一般是在类外部进行,因此构造函数声明为public。

      第一个为无参构造函数或默认构造函数,写这个函数的好处是当你在创建对象的时候并不想立即对它初始化,而是在后续的工作中再进行赋初值,即:
      Test test;
      如果没有默认构造函数则会报错。那么问题来了,之前的例子根本没写构造函数,却不会报错,这是为什么?
       
      因为在IDE里(ex:codeblocks)不会报错是因为IDE会自动生成一个默认构造函数。当然,如果你已经定义了一个有参的构造函数,它就不再为你自己生成一个默认构造函数,也就是说如果现在把这个Test类里的默认构造函数删除了,
      Test test;
      就会报错。
       

      第二个构造函数就完成了我们的初始化工作,它有两个形参,分别给数据成员a,b进行初始化,定义对象的时候传入了 3和4,则 a和b 被初始化为 3 和 4 。因此程序运行的结果是 打印出了 7。
       
      构造函数初始化列表
       
      所谓初始化列表,它的功能和我们写在函数体里的赋初值是一样的,也就是说可以写成如下形式:
       
      #include <iostream>
      
      using namespace std;
      
      class Test
      {
      public:
          Test ();
          Test (int x,int y);
          void Sum();
      private:
          int a,b;
      };
      Test::Test()
      {
      
      }
      Test::Test(int x,int y):a(x),b(y)
      {
      
      }
      void Test::Sum()
      {
          cout<<a+b;
      }
      int main()
      {
          Test test(3,4);
          test.Sum();
          return 0;
      }
      你可以选择写的更简洁一点:
      #include <iostream>
      
      using namespace std;
      
      class Test
      {
      public:
          Test () {}
          Test (int x,int y):a(x),b(y) {}
          void Sum();
      private:
          int a,b;
      };
      
      void Test::Sum()
      {
          cout<<a+b;
      }
      int main()
      {
          Test test(3,4);
          test.Sum();
          return 0;
      }
      那么这样做和普通的赋值有区别吗?
      当然是有的,对于一般的变量,两种都可行,但是如果需要初始化的是类类型的成员,则必须使用构造函数初始化列表。比如:
       
      #include <iostream>
      
      using namespace std;
      
      class Test
      {
      public:
          Test () {}
          Test (int x,int y):a(x),b(y) {}
          void Sum();
      private:
          int a,b;
      };
      
      void Test::Sum()
      {
          cout<<a+b;
      }
      class AnotherTest
      {
      public:
          AnotherTest(int i,int j):test(i,j) {test.Sum();}
      private:
          Test test;
      };
      int main()
      {
          AnotherTest test(3,4);
          return 0;
      }
      
       
      之前说过,类的成员函数可以重载,带默认参数等,那么构造函数呢?
      构造函数也是可以的,刚才那个例子就是构造函数的重载,默认构造和有参构造。

      下面是一个带默认参数的构造:
      #include <iostream>
      
      using namespace std;
      
      class Test
      {
      public:
          Test () {}
          Test (int x = 0,int y = 0):a(x),b(y) {}
          void Sum();
      private:
          int a,b;
      };
      
      void Test::Sum()
      {
          cout<<a+b;
      }
      
      int main()
      {
          Test test(3);
          test.Sum();
          return 0;
      }
      一旦指定了 x = 0,就必须指定 y 的值。
       
      Test (int x = 0,int y):a(x),b(y) {}
      这样是错误的。


      复制构造函数
       
      复制构造函数也称为拷贝构造函数,它的作用是用一个已经生成的对象来初始化另一个同类的对象。
      即实现如下功能:
      Test test1(3,4);
      Test test2 = test1;
      复制构造函数的写法:
       
      类名 (const 类名& obj)
      {
             函数体
      }
       
      例如:
      #include <iostream>
      
      using namespace std;
      
      class Test
      {
      public:
          Test () {}
          Test (int x ,int y):a(x),b(y) {}
          Test (const Test& t):a(t.a),b(t.b) {}
          void Sum();
      private:
          int a,b;
      };
      
      void Test::Sum()
      {
          cout<<a+b;
      }
      
      int main()
      {
          Test test1(3,4);
          Test test2 = test1;
          test2.Sum();
          return 0;
      }
      
      程序运行的结果是 7 ,它完成了给test2进行初始化。
      当然也可以用如下语句:
      Test test2(test1);
      深复制和浅复制:
       
      如果不定义复制构造函数,以上对象也可以这样进行初始化,原因就是系统也会自己生成一个复制构造函数。
      现在存在这样一个类:
      #include <iostream>
      #include <cstring>
      
      using namespace std;
      
      class Test
      {
      public:
          Test (int x,char *ptr)
          {
              a = x;
              p = new char [x];
              strcpy(p,ptr);
          }
          Test (const Test& C)
          {
               a = C.a;
               p = new char [a];
               p = C.p;
          }
          void Print();
      private:
          int a;
          char *p;
      };
      
      void Test::Print()
      {
          int i = 0;
          while(p[i] != '\0')
          {
              cout<<p[i];
              i++;
          }
      
      }
      
      int main()
      {
          char p[5] = "test";
          Test a(10,p);
          Test b(a);
          b.Print();
          return 0;
      }
      

       
      因为对象 a 和 b 指向的是同一段内存区域,如果我们在完成复制(浅复制)之后删除了 a,它指向的内存区域同样也被删除了,而此时 b 此时仍然指向的是这片区域,如果再把 b 删除掉,同一片内存区域被释放两次,这明显是错误的。也就是说,浅复制只是简单的将 a 中p 的值给了 b 中的 p。那么要解决这个问题就得用到深复制:
      Test (const Test& C)
          {
               a = C.a;
               p = new char [a];
               if(p != 0)
                 strcpy(p,C.p);
          }
       
       
      析构函数:
       
      析构函数在类里起了一个“清理”的作用,比如类中有需要动态开辟内存的成员,而在程序结束之后我们需要释放内存,这时只要将释放内存的语句写在析构函数中,而系统在程序运行结束之后会自动执行析构函数,进行内存的释放以及对象的销毁。
      以下是一个例子:
      #include <iostream>
      #include <cstring>
      
      using namespace std;
      
      class Test
      {
      public:
          Test (int x,char *ptr)
          {
              a = x;
              p = new char [x];
              strcpy(p,ptr);
          }
          Test (const Test& C)
          {
               a = C.a;
               p = new char [a];
               if(p != 0)
                 strcpy(p,C.p);
          }
          ~Test()
          {
              delete (p);
              cout<<"p has been destroyed"<<endl;
          }
          void Print();
      private:
          int a;
          char *p;
      };
      
      void Test::Print()
      {
          int i = 0;
          while(p[i] != '\0')
          {
              cout<<p[i];
              i++;
          }
          cout<<endl;
      }
      
      int main()
      {
          char p[5] = "test";
          Test a(10,p);
          Test b(a);
          b.Print();
          return 0;
      }
      
      程序运行结果如下:
       
      由此可见,a 和 b 的析构函数都被调用了。 
       
       
       

      5.友元机制:

      C++提供了友元机制,允许一个类将其非公有成员的访问权限授予指定的函数或类。友元的声明只能在类定义的内部,因此,访问类非公有成员除了自身成员,还有友元。
      有如下程序:
      #include <iostream>
      #include <cstring>
      
      using namespace std;
      
      class Test
      {
      public:
          Test (int a)
          {
              x = a;
          }
          ~Test()  //析构函数
          {
      
          }
          friend void Print(Test& a,Test& b);
      private:
          int x;
      };
      
      void Print(Test& a,Test& b)
      {
          cout<<a.x*b.x;
      }
      
      int main()
      {
          Test a(10);
          Test b(3);
          Print(a,b);
          return 0;
      }
      
      输出结果为 30 ,完成了求两个对象内的数据之积。
       
      下面介绍友元类:
      #include <iostream>
      #include <cstring>
      
      using namespace std;
      
      class B;  //类的前向声明
      class A
      {
      public:
          A(){}
          ~A()  //析构函数
          {
      
          }
          void Print(B& a);
      };
      
      class B
      {
      public:
          B (int a)
          {
              x = a;
          }
      private:
          int x;
          friend void A::Print(B& a);
      };
      void A::Print(B& a)
      {
          cout<<a.x;
      }
      int main()
      {
          B test1(3);
          A test2;
          test2.Print(test1);
          return 0;
      }
      
       类A成功的访问了类B的私有成员,并且打印出来。输出结果为 3。

      友元类的关系是单向的,即 A 是 B 的友元,B 不是 A 的友元,类 B 不能访问 A 的数据成员。此外,友元的关系不能传递或继承,类 B 是类 A 的友元,C 是 B 的友元,那么 C 不是 A 的友元,除非另外声明一次。
       

      6.继承与派生:

       
      继承是面向对象程序设计的一个重要特性,继承允许在原有类的基础上创建新的类,举个例子,现在有一个平行四边形类,而菱形类,矩形类,正方形类 都属于平行四边形类,它们有一个共同点,那就是需要两条边长来描述图形,如果不采用继承,我们需要在每个类中定义两个数据成员,那样会显得很繁琐。下面我们看一个计算矩形面积的例子:
      #include <iostream>
      
      using namespace std;
      
      class Parallelogram
      {
      public:
          Parallelogram(int a,int b):length(a),width(b) {}
          int getLength(){return length;}
          int getWidth() {return width;}
      private:
          int length,width;
      };
      class Rectangle : public Parallelogram  //公有继承
      {
      public:
          Rectangle(int a,int b):Parallelogram(a,b) {}  //先对基类中的数据成员进行初始化
          void Area()     //计算面积
          {
              cout<<getLength()*getWidth();
          }
      };
      int main()
      {
          Rectangle r(3,4);
          r.Area();
          return 0;
      }
      
      首先说一下继承方式,c++提供了三中继承方式。
      public(公有继承),基类中的公有和保护成员保持原属性,私有成员为基类私有。
      private(私有继承),基类中的所有成员在派生类中都是私有的。
      protected(保护继承),基类的公有成员和保护成员在派生类中成了保护成员,私有成员仍为基类私有。
       
      现在我们说如何设计一个派生类:
      ①从基类接收成员,除了构造函数和析构函数,派生类会把全部的成员继承过来,这是没有选择的。
      ②调整基类成员的访问。
      ③修改基类成员,可以在派生类中声明一个与基类同名的成员,此操作会覆盖基类的同名成员。
      ④在定义派生类的时候定义新的成员,定义构造函数和析构函数,初始化的时候必须先将基类的成员初始化(因为并没有继承基类的构造函数)之后才可以对派生类的成员进行初始化。析构函数也一样,需要在派生类中释放基类的数据成员(调用基类的析构函数)。
       
      上面这个程序定义了一个基类(平行四边形类),它含有两个数据成员,代表两个边长,而矩形在计算面积的时候需要两个边长的长度,也就是长和宽,因此继承平行四边形类,并且新添加了计算面积的函数,程序输出结果 12。
       
       
      多重继承和虚基类:
      C++还支持一个派生类同时继承多个基类。
      多重继承派生类的定义:
       
      class  派生类名 : 访问标号1 基类名1 , 访问标号2 基类名2 , ....

      {

               成员列表

      }

      同样,派生类的构造函数初始化列表在调用基类构造函数也应该按定义时的先后次序。

      接下来看个例子:

       

      #include <iostream>
      
      using namespace std;
      
      class BaseOne
      {
      public:
          BaseOne() {cout<<"This is BaseOne"<<endl;}
          BaseOne(int a):data(a) {cout<<"BaseOne's data is "<<data<<endl;}
      private:
          int data;
      };
      
      class BaseTwo
      {
      public:
          BaseTwo() {cout<<"This is BaseTwo"<<endl;}
          BaseTwo(int a):data(a) {cout<<"BaseTwo's data is "<<data<<endl;}
      private:
          int data;
      };
      
      class BaseThree
      {
      public:
          BaseThree() {cout<<"This is BaseThree"<<endl;}
      };
      
      class Derive:public BaseOne,public BaseTwo,public BaseThree
      {
      public:
          Derive () {cout<<"This is Derive"<<endl;}
          Derive (int a,int b,int c,int d,int e):BaseOne(a),BaseTwo(b),dataOne(c),dataTwo(d),data(e)
          {cout<<"Derive's data is "<<data<<endl;}
      private:
          BaseOne dataOne;
          BaseTwo dataTwo;
          int data;
      };
      
      int main()
      {
          Derive r1;
          cout<<endl;
          Derive r2(1,2,3,4,5);
          return 0;
      }
      

       

      程序运行结果如下:

       

      在调用派生类的默认构造函数时,即使没有写出调用基类的默认构造函数,系统也会调用基类的默认构造函数,而在结果的第4 , 5行还调用了一次,原因是派生类里有两个基类的数据成员,因此我们可以观察到,程序先调用了基类的构造函数,然后调用派生类中子对象的构造函数,最后调用派生类的构造函数。

      在调用构造函数的时候,先调用基类的构造函数,虽然BaseThree没有参数,但是仍然会调用它的构造函数,然后初始化子对象,调用构造函数,最后调用派生类的构造函数。

       

      二义性问题:

      假定我们有如下程序:

       

      #include <iostream>
      #include <cstring>
      
      using namespace std;
      
      class A
      {
      public:
          void fun() {cout<<"This is A"<<endl;}
      };
      
      class B
      {
      public:
          void fun() {cout<<"This is B"<<endl;}
      };
      
      class C:public A,public B
      {
      public:
          void hun() {fun();}  //产生二义性
      };
      
      int main()
      {
          C c;
          c.hun();
          return 0;
      }
      

       

      相信看到这里大家都知道二义性问题的产生原因了吧,就是两个基类存在名称相同的数据成员,而派生类在调用基类数据成员的时候如果没有显式的指出它属于谁,那么程序就会产生错误,现在做如下修改:

       

       

      void hun() {A::fun(); B::fun();}

       

      这次程序会分别调用 A 和 B 的 fun() 函数。我们要做的只是在它前面写上 基类名加上域运算符 :: ,当然也可以通过 对象名.基类名 :: 和 对象指针名.基类名 :: 这两种方式。

       

       

      虚基类:

      假定现在有这样一种继承关系:

       

      #include <iostream>
      
      using namespace std;
      
      class A
      {
      public:
          void fun() {cout<<"This is A"<<endl;}
      };
      
      class B:public A
      {
      public:
          void gun() {cout<<"This is B"<<endl;}
      };
      
      class C:public A
      {
      public:
          void hun() {cout<<"This is C"<<endl;}
      };
      
      class D:public B,public C
      {
      public:
          void kun() {fun();} //产生二义性
      };
      
      int main()
      {
          D d;
          d.kun();
          return 0;
      }
      

       

      A 是基类,B 是 A 的派生类,C 也是 A 的派生类,而 D 是 B 和 C 的派生类,因此 D 可以访问 A 的数据成员,但现在会产生二义性问题,我们必须显式的指出 fun() 是来自 B 的 还是来自 C 的,但是我们都知道它来自 A , 因此我们希望找到一种方式,使得在继承间接共同基类时只保留一份成员,这就用到了虚基类的机制。

       

      虚基类是在派生类定义时,指定继承方式时声明的。声明的一般形式:

       

      class  派生类名 : virtual  访问标号 虚基类名 , ...

      {

              成员列表

       

      为了保证虚基类在派生类中只继承一次,应当在所有直接派生类中声明为虚基类。依然是上面那个程序,只需要:

       

      class B:virtual public A

       

      class C:virtual public A

       

      这样在类 D 中调用 fun() 函数,就不用指出它究竟属于谁。

       

      接下来看看虚基类构造函数和析构函数的一些特性。

      有这样一个程序:

       

      #include <iostream>
      
      using namespace std;
      
      class A
      {
      public:
          A() {cout<<"This is Grandpa"<<endl;}
          A(int a):One(a) {cout<<"Grandpa is "<<One<<" years old"<<endl;}
          ~A() {cout<<"A is over"<<endl;}
      private:
          int One;
      };
      
      class B:virtual public A
      {
      public:
          B() {cout<<"This is father"<<endl;}
          B(int a,int b):A(a),Two(b) {cout<<"father is "<<Two<<" years old"<<endl;}
          ~B() {cout<<"B is over"<<endl;}
      private:
          int Two;
      };
      
      class C:virtual public A
      {
      public:
          C() {cout<<"This is mother"<<endl;}
          C(int a,int b):A(a),Three(b) {cout<<"mother is "<<Three<<" years old"<<endl;}
          ~C() {cout<<"C is over"<<endl;}
      private:
          int Three;
      };
      
      class D:public B,public C
      {
      public:
          D() {cout<<"This is me"<<endl;}
          D(int a,int b,int c,int d):A(a),B(a,b),C(a,c),Four(d) {cout<<"I am "<<Four<<" years old"<<endl;}
          ~D() {cout<<"D is over"<<endl;}
      private:
          int Four;
      };
      
      int main()
      {
          D d1;
          cout<<endl;
          //D d2(65,40,39,13);
          return 0;
      }
      

      首先看默认构造函数(先把d2注释掉),程序运行结果如下:

      程序会自动调用构造函数,首先调用虚基类的构造函数,然后再根据派生类继承的次序调用构造函数,如果先继承了 C 类,那么先调用 C 类的构造函数。析构函数的调用则正好相反。

       

      接下来看有参的,给 d1 加上注释,去掉 d2 的注释,程序运行结果如下:

      调用次序是一样的,因此虚基类的构造函数优先于非虚基类的构造函数进行执行,如果在虚基类中定义了带参数的构造函数,而且没有定义默认构造函数,则在其所有的派生类里(直接和间接)中,都必须通过构造函数的初始化列表对其进行初始化,在最后的派生类中不单单对直接继承的类进行初始化,还要对虚基类进行初始化。

       

       

      7.多态性和虚函数:

       

      首先介绍一下多态性,多态是指同样的消息被不同类型的对象接收时导致不同的行为,举个通俗易懂的例子,假定现在有一个模具,这个模具是一个人型模具,根据倒入里面金属液体的不同,它最终会形成不同类型的器件,如果倒入的是液体黄金,那么它会形成一个小金人,如果倒入的是铁水,那就会形成一个小铁人,多态大概就是这样的意思。

       

      多态性可以通过很多方法实现,而我们要说的是 包含多态 实现多态性,C++采用虚函数实现包含多态,至少含有一个虚函数的类成为多态类。

      在介绍虚函数之前,我们介绍两种联编。联编就是将模块或者函数合并在一起生成可执行代码的处理过程,同时对每个模块或者函数分配内存地址,并且对外部访问也分配正确的内存地址。

      在编译阶段就将函数实现和函数调用绑定起来称为静态联编,程序运行的时候才进行函数实现和函数调用的绑定称为动态联编。

      举个例子:

       

      #include <iostream>
      
      using namespace std;
      
      class A
      {
      public:
          void fun() {cout<<"Use A"<<endl;}
      };
      
      class B : public A
      {
      public:
          void fun() {cout<<"Use B"<<endl;}
      };
      
      int main()
      {
          B b;
          A *p = &b;
          p->fun();
          return 0;
      }
      

       

      我们声明了一个指向类 B 的指针,但是程序的输出结果是:

       

      之所以会这样是因为将其定义为 A 类型,程序在编译阶段就已经确定 A 类型的指针调用的 fun() 是 A 类的成员。

      接下来看动态联编:

      给刚才类 A 的 fun() 函数前面加上 virtual ,

       

      virtual void fun() {cout<<"Use A"<<endl;}

      将其定义为了虚函数,再次运行:

      当编译器编译含有虚函数的类时,将为它建立一个虚函数表,相当于一个指针数组,存放每个虚函数的入口地址,编译器为该类增加一个额外的数据成员,这个数据成员是一个指向虚函数表的指针,通常称为vptr。这个例子中,A 类有一个虚函数 fun() , 所以虚函数表里只有一项,如果派生类没有重写这个虚函数,那么虚函数表里的元素所指向的地址就是基类虚函数的地址,重写之后,则 vptr 指向派生类的虚函数地址。

      派生类可以继承基类的虚函数表,而且只要和基类同名的成员函数,无论前面加不加 virtual ,都会自动成为虚函数,虚函数的调用规则是,根据当前对象,优先调用对象本身的成员函数。

       

      虚析构函数:

      如果将基类的析构函数声明为虚函数,那么其派生类的析构函数也变为虚析构函数,即使名字不同,当基类的析构函数是虚析构函数时,无论指针指的是同一类族中的哪一个类对象,系统总会采用动态联编,调用正确的析构函数,对该对象进行清理。C++中,不支持虚构造函数。

       

      纯虚函数:

      许多情况下,不能在基类中为虚函数给出一个有意义的定义,那就将其声明为纯虚函数,具体怎么实现交给派生类去做,纯虚函数的定义形式为:

       

      virtual   返回类型  函数名 (形式参数列表) = 0;

       

      纯虚函数的作用是在基类中为其派生类保留一个函数的名字,以便派生类根据需要对其进行定义,如果一个类里声明了虚函数,而在其派生类中没有对该函数定义,那么该函数在派生类中仍然为纯虚函数。含有纯虚函数的类成为抽象类,抽象类不能定义对象,如果派生类里给出了抽象类中纯虚函数的实现,那么该派生类不再是抽象类,否则仍然是抽象类。抽象类至少含有一个纯虚函数。

       

      接下来看一个计算圆形面积和圆柱体体积的程序:

       

      #include <iostream>
      
      using namespace std;
      
      class Sharp
      {
      public:
          virtual double area() = 0;
          virtual double volumn() = 0;
      };
      
      class Circle : public Sharp
      {
      public:
          Circle(double r):R(r) {}
          virtual double area() {return 3.1415926*R*R;}
          virtual double volumn() {return 0;}
      private:
          double R;
      };
      
      class Cylinder : public Circle
      {
      public:
          Cylinder(double a,double b):Circle(a),H(b) {}
          virtual double volumn() {return area()*H;}
      private:
          double H;
      };
      
      int main()
      {
          Circle a(20.0);
          Cylinder b(10.0,2.0);
          cout<<a.area()<<endl;
          cout<<b.volumn()<<endl;
          return 0;
      }
      

       

      程序运行结果:

       

      展开全文
    • 摘抄“GPU Programming And Cg Language Primer 1rd Edition” 中文名“GPU编程与CG语言之阳春白雪下里巴人” 数据(Volume Data)学习任何一门技术,首先要弄清楚这项技术的起源以及数据来源。技术的起源也就是...
    • 【C】C语言结构体、共用和枚举

      千次阅读 多人点赞 2018-05-11 14:22:17
      在C语言中,数据类型可分成基本数据类型、构造数据类型、指针数据类型、空类型四大。本文主要介绍构造数据类型——结构体、共用。除了这两个之外,还会介绍到枚举。 结构体概述 结构体是一系列具有相同类型...
    • (本章的学习量相对比较大,我把整体分为三个部分讲解,第一个部分和第二个部分为Java关于和对象以及OO的基础,第三个部分为在OO设计技巧中针对Java程序的一些性能提升的小技巧,因为尽量保证Java关于和对象的...
    • 绘制的原理和Raycasting的实现

      千次阅读 2014-06-05 16:22:42
      绘制 “ 在某一密度条件下,光线穿越时,每个体素对光线的吸收发射分布情况 ”
    • JVM成神之路-加载机制-双亲委派,破坏双亲委派

      万次阅读 多人点赞 2018-08-21 09:24:50
      从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载、验证、准备、解析、初始化、使用、卸载。其中验证、准备、解析统称为连接 上图中,加载、验证、准备、初始化和卸载这5个阶段的顺序...
    • 《REWORK》启示录 发出你的心声——程序员与身体

      万次阅读 多人点赞 2013-11-14 17:14:30
      这是一篇适合给程序员看的关于健康的...不过,我想这样的人还有很多,只是我们不了解罢了,李是其中比较出名的一个。这算是其中的一个目的,问题是有谁会在刚开始工作的时候,就开始注意这种基本简单的问题——身体。
    • java 第七章 内部与异常

      千次阅读 多人点赞 2017-12-10 17:46:09
      1. java支持在一个中定义另一个...(2)内部类体中不可以声明变量和方法。外嵌类体中可以用内部声明对象,作为外嵌的成员;(3)内部仅供它的外嵌使用,其他不可以用某个的内部声明对象。
    • 面试官,不要再问我“Java虚拟机加载机制”了

      万次阅读 多人点赞 2019-10-27 16:28:39
      关于Java虚拟机加载机制往往有两方面的面试题:根据程序判断输出结果和讲讲虚拟机加载机制的流程。其实这两题本质上都是考察面试者对Java虚拟机加载机制的了解。 面试题试水 现在有这样一道判断程序输出结果...
    • 详解 Java 内部

      万次阅读 多人点赞 2018-09-04 00:17:56
      从种类上说,内部可以分为四类:普通内部、静态内部、匿名内部、局部内部。我们来一个个看: 普通内部 这个是最常见的内部之一了,其定义也很简单,在一个里面作为的一个字段直接定义就可以...
    • 人体骨骼关键点检测综述

      万次阅读 多人点赞 2018-06-11 12:53:45
      多人人体骨骼关键点检测主要有两个方向,一种是自上而下,一种是自下而上,其中自上而上的人体骨骼关键点定位算法主要包含两个部分,人体检测和单人人体关键点检测,即首先通过目标检测算法将每一个人检测出来,然后...
    • MFC 设置字体

      万次阅读 2013-10-09 16:30:00
      CFont是CGDIObject的派生:CObject → CGDIObject → CFont。只有一个缺省构造函数CFont( ); 必须用下列字体创建成员函数CreateFont[Indirect]或CreatePointFont [Indirect]来初始化。  其中的CreatePointFont...
    • 【C++】C++和对象、构造函数和析构函数

      千次阅读 多人点赞 2018-06-03 20:32:37
      是对某一事物的抽象描述,具体地讲,是C++中的一种构造的数据类型。它即可包含描述事物的数据,又可包含处理这些数据的函数,在程序运行时是被用作样板来建立对象的。所以要建立对象,首先必须定义。 ...
    • 微信小程序引用外部字体

      万次阅读 2017-01-13 20:59:10
      微信小程序如何引入外部字体库微信小程序的霸权主义, 不识别很多文件, 其中包括外部的字体文件. 那我们怎么突破他的防火线呢, 这里主要用得就是在线的字体库. 它的使用不像之前引用阿里巴巴字体库那样简单, 有一点...
    • 【转】拜占庭政治经济

      万次阅读 2019-05-12 07:59:12
      我们在这篇文章中的论点很简单:密码学家所说的拜占庭容错和经济学家指的强大政治经济是一回事。 结果这一发现对于理解经济思想史和制度加密经济学(编者注:中译本见文末。)方向有重大影响。 但是为了解释原因...
    • GDI+学习及代码总结之------文本与字体

      万次阅读 多人点赞 2013-06-14 19:12:12
      GDI+中将具有相同字样、包括不同风格的字体称为字体系列。字体从其系列中获得名称、重量(如粗体、规则、加亮)以及风格。例如Arial字体系列包含了下列4种字体: Arial Regular(规则)、Arial Bold(黑体)、Arial ...
    • 基于3D关节点的人体动作识别综述

      万次阅读 2017-12-04 21:56:14
      叶节点存储条件分布(其中类指示正文部分)。为了对深度图像中的像素进行分类,根据存储在分离节点中的特征和阈值的比较结果,将每一棵树向左或向右分支遍历。一旦到达叶节点,像素被分配存储在叶节点中的-条件...
    • 03-视觉的主要任务就是感知外部环境,这里的过程部分都有共性,三维环境投影至二维,再呈现出来会有一些奇特的现象,可以看左面图片,通过经验可以帮助我们理解这些,经验来源于学习和积累,对计算机而言就是机器...
    • 一、为什么要使用加载器? Java语言里,加载都是在程序运行...2.用户可以自定义一个加载器,让程序在运行时从网络或其他地方加载一个二进制流作为程序代码的一部分;(这个是Android插件化,动态安装更新apk的基础
    • 九、基于智能的模型 原文:Chapter 9 Agent-based models 译者:飞龙 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译 我们迄今为止看到的模型可能具有“基于规则”的特征,因为它们涉及受简单规则支配的...
    • 类体包括成员变量和局部变量,而成员变量又可以细分为实例变量和变量,在声明成员变量的时候,用static给予修饰的称作变量,否则称作实例变量。 那么,变量和实例变量有什么区别呢? 我们知道,一个通过...
    • NLP之文本分类

      万次阅读 2018-09-26 15:08:07
      文本自动分类简称文本分类(text categorization),是模式识别与自然语言处理密切结合的研究课题。传统的文本分类是基于文本内容的,研究如何将文本自动划分成政治的、经济的、军事的...文本分类是在预定义的分类...
    • } } } 其中,GenericServlet抽象相比于直接实现Servlet接口,有以下几个好处: 1.为Servlet接口中的所有方法提供了默认的实现,则程序员需要什么就直接改什么,不再需要把所有的方法都自己实现了。 2.提供方法,...
    • C++的定义

      万次阅读 2016-10-08 22:32:48
      是面向对象程序设计的核心,它实际是一种新的数据类型,也是实现抽象类型的工具,因为是通过抽象数据类型的方法来实现的一种数据类型。是对某一对象的抽象;而对象是某一种类的实例,因此,和对象是密切...
    • 1.UML将分为三种:1.边界(Boundry Class); 2.实体(Entity Class); 3.控制(Control Class);...这种交互包括转换事件,并记录系统表示方式(例如接口)中的变更。一个系统可能会有多种边界:用户界面 -
    • Java的组成

      千次阅读 2019-04-15 00:21:11
      的组成是什么?由什么成分组成?定义语法格式可分为成员变量局部变量可分为:方法...其中,分为 四大人种:亚洲人种(黄种人)、高加索人种(白种人)、非洲人种(黑种人)、大洋洲人种(棕种人) 共同...
    • 人体呼吸信号的数据挖掘

      千次阅读 2016-09-14 23:37:39
      生理信号中的呼吸信号是一典型的时间序列信号,可以从移动设备检测到的心电信号中提取得到或者采用其它方式获取,对呼吸信号进行分析并挖掘其中的异常呼吸事件 对研究人体睡眠质量及其他心脑血管疾病有极大的帮助...

    空空如也

    空空如也

    1 2 3 4 5 ... 20
    收藏数 293,156
    精华内容 117,262
    关键字:

    其中类体部分包括