范磊C++ 原创笔记 第六章 面向对象
来源:互联网 发布:温职院网络课程 编辑:程序博客网 时间:2024/04/26 15:20
类名与结构体相似:
类与结构体相似,都是混合型数据组成一个整体。都是要先定义数据类型。这个数据类型的名称有一半也是自己定义的。
如 class human
{
public :
private:
};
human是自定义的名称,但他不是变量名,而是数据类型。
声明完数据类型,才能定义具体的对象名。
注:public private可以不写,不写的话所有数据默认属于private。但构造函数不管怎样一律属于公有,默认也是公有。特意写在private里面会报错。
注:
一、声明一个类,其中变量成员不能具体赋予数值初始化,这样会报错。要初始化赋值要先创建对象,通过对象来初始化赋给具体的值。
二、类中成员函数中的变量,可以被直接初始化赋值
三、虽然成员变量在类里不能被直接赋值为具体数据,但可以有赋值关系式 ,如: int a = b; a = b+ 1;
类成员函数的内外部定义:
内部就是在类后面的括号里定义。而外部就是在类括号外面定义。我们可以在内部先声明一个成员函数,然后再在外部定义,也可以在内部声明并定义。
在内部定义的话,那就是一般的定义函数的写法。
Class A
{
Void chengyuan ()
{
int a = 33;
int b = a;
}
};
而外部,则需要
void A :: chengyuan ()
{
int a = 33;
int b = a;
};
其中A是类名。类名后面加两个冒号。(至于后面谈到内联函数时,会再谈到函数声明与函数定义的形式)
注意:函数定义时,返回值类型,跟参数都需要再写。没有为什么,就算声明的时候已经写了,定义的时候还是要再写。
如何定义一个对象:
如: human jack;
这个jack就是对象名。他是class human类型
human是之前已经声明的类名,jack是自己取的对象名。这个时候这样写已经是定义而不是声明,运行时会给对象里面的各种变量分配空间。
(这里的声明与定义的概念很复杂,之后会讲)
如何一次性定义多个对象:定义数组对象
如: human jack[ 10 ];
这表示创建了jack [ 0 ]~~~jack [ 9 ]的10个对象,在内存空间中连续存放。
类中的public private到底是什么?有什么用?
跟C语言结构体相比,类多了public 跟private 。重点在于private 。 凡是private里面的成员,想要访问他们,调用他们,必须通过public成员。
其他形式调用不了。
C语言的结构体里面的数据,就好比是公用图书馆,这个图书馆只有一楼,所有书都放在一楼。
类中private,好比是公用图书馆改进了,变成了两层楼。想进二楼看图书,你必须要先进一楼,没有其他办法。
一楼相当于public , 不管你怎么来的,你可以打的过来,你可以散步过来,你可以公交过来。
但要进二楼的人,必须是通过一楼那几个梯子。你必须是先到一楼,必须是要上一楼的梯子,这是你上来的条件。
也就是说,类对数据进行了分类,public里面的数据谁都能访问,调用。但private 的数据只能通过调用public成员,public成员再调用private这样子来间接调用。
而且往往调用的是那些public成员函数,因为这些函数里面含有访问private的代码。如:
public :
int func (int a)
{
int a = b;
};
其中b 是private成员。那么调用func函数,就间接访问了private成员。至于为什么要有公有私有成员,这是为了方便,为了隐私,有些数据时需要权限来访问的。这也是为了数据的安全性考虑,增加安全性。具体初学也难以给予复杂的实际例子说明,具体不用深入研究。
就是说,private里面的数据,读取或者修改,只能由public发出命令才行。如果用户直接命令修改数据,读取数据,是不行的。同时,private也只能把数据发给public接受。public一面链接着用户,一面链接着private。private不与用户直接连通,必须要以public为桥梁。
private的默认性:
前面说过,如果用户不写public private 而直接写类的内容,那么内容全部属于private (其中,构造函数,析构函数,复制构造函数等除外,之后会讲到)
什么是内联函数?内联函数的声明:
内联函数就是在函数声明那里加一个关键词inline 。
我们在调用函数时,是跳回到上面函数的定义部分进行执行,这样的话有一个跳转的步骤,如果程序调用的多了,那么程序速度会变慢,所以,我们加上inline后,编译时直接把调用部分替换成函数定义部分,也就是把函数定义部分在此地给复制一份。这样运行时,就不用跳转了。直接在当地执行。
但复制缺点就是会增加程序的体积。 成员函数的内联跟普通函数内联表达上一致,就不多说了。
内联函数声明举例: inline int func (int); 其中参数只有Int 表示接受的是int类型,具体参数名在定义时函数头给出。
函数声明与定义的注意:
函数的声明包含附加关键词(如linline), 函数返回类型,函数名,跟参数或者只有参数类型。
函数定义如果跟声明分开,那么定义的函数头部分必须要有函数返回类型,函数名,参数类型参数名 ,哪怕声明时已经写过了,定义时还要再写。而附加关键词可以不写(如linline, 声明时如需要一定要写,定义时不用写。)
const 用法:五个const的含义:
void p(int x ,int y) const
{
i = x;
};
注意:const在大括号前面,表示大括号里面的成员数据不可以修改,不可以被赋值。这个位置使用const,这个函数必须是成员函数。普通函数不能在这个位置用const . 这里企图对x成员数据进行赋值,会报错。
百度上说应该多用const 。自己想了一下觉得也有道理,因为真正的程序代码很多很复杂,也许一个代码变动就不经意间修改了你不想修改的数据。而const可以作为一个把关,就好比是一个免疫机制,出现不正常了,立刻报错!
普通函数四个const 含义:
const A * const func (const A * const one)
/*1*/和/*2*/修饰返回值
/*1*/限定返回值(类型是指针)指向的对象的值不可修改
/*2*/限定返回值指向的是哪个对象不可修改
/*3*/和/*4*/修饰函数的唯一一个参数,即one
/*3*/限定one指向的对象的值(在函数内)不可修改
/*4*/限定one指向的是哪个对象(在函数内)不可修改
const在 * 左边是表示不能改变指针指向的对象的值,在 * 右边是表示不能改变指针指向的内存地址。规定就是这样……所以说总是写成double const pi=3.1415926;这样始终放在被修饰的类型后面才是好习惯……
初步构造函数介绍:
一、默认构造函数的存在
默认构造函数,就是隐藏的函数,它存在于类的public 中,每一个类都会有(只要我们不重新定义不覆盖,之后会讲)
human ()
{
};
这个就是默认构造函数。它看不到,是隐身的。它的函数名就是类名。默认的构造函数没有参数,没有内容。
二、构造函数的意义与自定义构造函数
当我们创建对象,就会先自动调用构造函数,这是内部的设定,就是这样。至于为什么这样,我想是因为方便初始化,把需要初始化的内容定义在构造函数里面,然后一传关键的参数,一调用,马上就给出想要的变量结果。
调用完构造函数,对象就创建好了。可以说,构造函数用于构造对象。
如果是默认构造函数,那么这个构造函数什么都不做,而前面所学规定,类的成员变量不能在类中直接被初始化,所以如果我们创建对象,调用默认构造函数,那么对象里面的变量大部分是垃圾值。
如果我们想创建对象后就自动填上值而非手动一个个赋值,那该怎么办呢?————那就自定义构造函数。
如:
human (int a, int b)
{
int a = weight;
int b = high;
}
之前我们创建对象,是 human jack ; 那是针对默认构造函数。因为它没参数。而现在参数变成两个了。所以创建对象的时候,要变成 human jack(80,180); ————这个式子之后再详细讲
也就是说,要创建对象,必须先调用构造函数,那么必须要传与构造函数对应的参数才行。
而此时默认构造函数已经消失,因为有了自定义构造函数,就会自动覆盖默认构造函数。
前面说,默认构造函数是隐身的,如果我们把他写出来,然后再写一个自定义构造函数,那么一样是覆盖,默认构造函数消失。
构造函数不能有返回值。关于构造函数还有很多内容,因为范磊这里只是稍稍提了一下,所以放到后面讲。
什么是析构函数,析构函数的作用:
析构函数跟构造函数一样,平时也是以默认析构函数存在,处于隐身状态。
它的形式为:
~human ()
{
}
就是比默认构造函数前面多了一个 ~
构造函数,在创建对象时会自动调用。析构函数,在作用域结束时,会释放作用域里的变量,当释放对象时,就自动调用析构函数来释放对象。
构造函数可以自定义,按照我们的方式来构造对象。析构函数也能自定义,但它只有自己的方式来析构对象。
我们可以在析构中加上一些其他内容比如cout 等。
自定义析构函数也会覆盖默认析构函数————但我觉得,它还是有析构的功能,这个问题问百度知道,无果。
构造函数不能有返回值,可以自定义参数,自定义内容。但析构函数不能有返回值也不能有参数,只能自定义内容。
对象数组的析构顺序:
当有多个对象被创建,析构时,是从最后被创建的最先开始析构。
自己的研究:
构造函数,是用来构造对象。
这句话我觉得表达上似乎不太好,(我是菜鸟,我在百度上问了很多人,纠结了很久很久),以为对象是靠构造函数构造的。
一个变量,无非是被分配内存跟初始化。被分配内存后,里面就已经有值了——垃圾值——垃圾值也是值。
而初始化,不过是覆盖垃圾值,只是一小小步骤而已。
构造函数,只是用来初始化此函数里面涉及到的一些成员变量(这些变量属于对象里的内容),但在这之前,成员变量的内存空间分配不是由构造函数来完成。
谁给对象分配了内存,谁才是构造了这个对象。构造函数只是往变量对应的内存里面填一些具体的数据而已,而且它也不一定是把所有成员变量都填上数据,有些可能还是保持垃圾值。构造函数,谈何能构造对象?
比如 class A
{
public :
int f ;
A (int a ,int b)
{
a = c;
b = d;
}
private:
int c;
int d;
}
然后我们 A a (1,2); 我们构造的对象中,是否有int f 这个变量呢? 答案是有的,但我们通过构造函数来构造对象啊,构造函数跟int f 扯不上关系,怎么对象中会有int f 呢?
构造函数,这构造对象的过程中,只是扮演一个小角色。
书上说,类不能被赋值。
原因是类是抽象名词,而不是具体某个个体,正如我们无法对int 这个类型进行赋值一样——————以上是范磊63页说的,但经过我的钻牛角尖后,觉得这样解释不太好。
疑点一:类里面的变量都不能被直接赋值吗?
百度答案:否。成员变量不能被赋值,但成员函数里面的变量可以直接初始化。
我疑问:既然成员函数的变量可以直接初始化,为何成员变量不行?
百度答案,百度贴吧答案:&*&%¥¥这个答案非常的复杂,饶到底层去了,讲了一大推天书语言,完全不懂。不过最后略微看懂了一点,那就是只有类,没有对象的时候,编译时还是会对类进行编译,还是会有类的信息。
自己的理解:我们创建对象时,怎样创建?天上掉下个对象?它如何创建,是根据类。也就是说,编译时对类里面的信息都进行了保存,类告诉程序,该怎样初始化对象。
我们不能对int 赋值,那是因为int 是完全的规定死了,没有一点可变性。但是作为数据类型的类,也是这样吗?
它凭什么不能被赋值?我声明一个人类,我规定人类都是有两只脚,不管是jack还是jim, 这样有问题么?
初始化碍着类什么事了?类是数据类型,int 其实也有初始化,它规定Int占用4字节难道不是一种初始化么?
我们不能对int 赋值,那么我们是无法对 human赋值,但我们怎么不能对human中涉及的变量来直接赋值呢?
所以说,类中不能直接初始化成员变量,我经过2天的痛苦研究求教,认为那只是规定,跟类是数据类型什么的没啥关系。
- 范磊C++ 原创笔记 第六章 面向对象
- java笔记第六章之面向对象
- 第六章 面向对象
- 第六章:面向对象
- 第六章 面向对象面向对象程序设计
- 《Effective C++》第六章:继承与面向对象设计
- [Python学习笔记][第六章Python面向对象程序设计]
- Effective C++ 第六章--继承与面向对象设计笔记
- 第六章 面向对象基础
- 面向对象第六章 异常
- 第六章-面向对象编程
- 第六章 C++面向对象程序设计
- C++面向对象程序设计 第六章 排序
- 第六章 继承与面向对象设计
- 第六章 继承与面向对象设计
- c++面向对象程序设计第六章作业
- 第六章:面向对象(二)
- 第六章:JavaScript面向对象编程
- pdf 文本转换为 java 字符串
- hdu 1381 Crazy Search(hash)
- 如何删除source insight中打开工程的历史记录
- RFT 实用CODE
- HDU 2087剪花布条(简单KMP)
- 范磊C++ 原创笔记 第六章 面向对象
- office2007下载地址
- Python多进程并发操作中进程池Pool的应用
- Dwr实现自动补全功能
- 在windows下写成批处理文件(.bat)顺序执行命令
- HTTP Header 详解
- sqlplus -oracle 11g 连接问题
- Linux常见命令记录
- Linux内核阅读--文件路径查找(二)