在其他语言中比如(Java,c#)可以直接判断类的对象是否是null来判断类的对象是否为空,但是在c++中由于指针的存在,不能直接判断类的对象,而应该判断指向对象的指针是否为空。
C++语言
中,对象没有空和不空的概念,只有
对象指针
才有空和不空的概念
判断
对象指针
是否为空只需要和NULL常量进行比较即可
如果相等,则为空,否则不为空
另外对象虽然没有空和不空的概念,但是有有效和无效的概念
当对象的
析构函数
被调用之后,对象即成为一个无效对象
一般可以用句柄法来判断
当对象被构造的时候,在一个全局的映射表中注册该对象,获得一个唯一句柄
判断的时候,用对象的句柄信息直接在映射表中进行查找,如果存在,则有效;如果不存在则无效
析构对象的时候,同时从映射表中删除该对象的句柄信息
这里还涉及到一个基础问题 就是指针的赋值,如下:
int *p1;
int i=2;
p1=&i;
long *p2=3;
p2的赋值明显是错误的,long *p2=3 这是在把3这个地址赋值给指针变量p2 , 但是3这个地址在计算中内存中是否可以访问(肯定不能访问)还是个未知数,这样很容易报错,非法访问内存,导致程序崩溃。
在网上看到一位同学的说法,解释的更清晰点:
long *p3=352; 这个和
long * p3;
p3=352; //注意*不和p3这个变量名结合
是一样的,把352赋值给p3,一是类型不匹配,再者如果真的赋值成功(用强制转换)那么p3指向的地址是352,这个地址不一定是可用的。
long *p3;
*p3=352;
这段代码编译没错,向p3指向的地址中放入352这个数,但是p3的值没有初始化,它指向的地址不确定,所以p3现在是野指针,运行时也可能程序崩溃。总之,p3和*p3是不一样的。
可以这样:
long a;
long * p3=&a; //等价于 long * p3; p3=&a;
*p3=352;
这时*p3和a都是352了。
char * c="abc";
这个等价于
char * c;
c="abc";
当然没问题,因为字符串或字符数组被编译器解析为地址。而字符串常量在编译时被编译器存贮在了静态的只读数据区。
// describe: 非虚函数情况下,将子
类
指针
赋给积累
指针
,验证最终调用
// 基
类
函数还是子
类
函数。
//==============================================================
#ifndef ANIMAL_H
#define ANIMAL_H
//=====================
C++
之父的
C++
圣经《
C++
程序设计语言 特别版》中说:
大家不要听某些人说
判断
指针
是否
为空
用(p==
NULL
)或(p!=
NULL
)的格式,
C++
之父认为这样写是不好的,提倡直接写(p)或(!p)的形式。 在win32开发中,if
(
NULL
== p )是极好的写法。但不要写成:if ( p ==
NULL
)
C++
之父主要是反对使用“
NULL
”,因为在某些特殊的开发环境叫,“N
需要注意的是,如果init_VaLue选择不当,导致在运行中可能被
赋值
(非初始化)初始值,那么这个
判断
就会失效。c/
c++
中,任何一个变量在定义后即拥有自身的内存空间,而内存空间中是一定有值的,所以不存在绝对意义上的空值。一般来说,
判断
空值都是
判断
定以后,
是否
被
赋值
过,所以只需要
判断
变量值
是否
还是初始值即可。strlen(s)==0 或者 s[0]=="\0" 效果相同,都可以起到
判断
效果。一般初始化为全0,可以通过
判断
长度,或者第一个字符值,来
判断
是否
为空
。所以对于
指针
p一般
判断
空值方式为。
隐藏
对象
的属性和实现细节,仅对外公开接口和
对象
进行交互。
封装实际上是由编译器识别关键字public,private,和protect,体现在
类
的成员可以有公有成员(public),私有成员(private),保护成员(protect)。
私有成员是封装体内被隐藏的部分,只有
类
的成员函数财可以访问私有成员,而在
类
体外的函数是不能访问的。公有成员是封装体与外界的一个接口,
类
体外的函数可以访问公有成员;保护成员是只有该
类
的成员函数和该
类
的派生
类
才可以访问的。
封装的作用是:降低
判断
一个
对象
是否
为空
es6中 Object.keys()方法返回
对象
的自身可枚举属性组成的数组,如果
对象
为空
,会返回一个空数组
var obj = { 'aa': 1, 'bb': 'b' }
var objEm = {}
Object.keys(obj) // ['aa', 'bb']
Object.keys(objEm) // []
所以,可以通过Object.keys()
判断
对象
的长度
是否
为空
if (Object.keys().length === 0) {
return true
在不改变数据库结构的前提下(假设你的数据是从数据库读取,而不是自己在代码中定义)。那么可以通过折中的方法来
判断
:
1 先通过 String.valueOf(int
类
型数据) 转换成String
类
型;
2 使用if(){ }
判断
“
null
” || "0"
是否
匹配你要
判断
的int
类
型数据即可;
DEMO:
if(“
null
”.equals( String.valueOf(你
if(b == {}){ console.log(4);}
if(b == '{}') { console.log(5);}
if(typeof(b) == 'object') { console.log(6);}
结果为:6
3. 代码3:
一、认识析构函数
百度百科:
析构函数(destructor) 与构造函数相反,当
对象
结束其生命周期,如
对象
所在的函数已调用完毕时,系统自动执行析构函数。析构函数往往用来做“清理善后” 的工作(例如在建立
对象
时用new开辟了一片内存空间,delete会自动调用析构函数后释放内存)。(咱也看不懂,直接上代码)。
这里我们来简单说说
类
的析构函数,它是
类
的一个成员函数,名字由波浪号加
类
名构成。看它的名字...
1.if(!p){ ... }
p为0,!p为真,if(!p)即
指针
为0或者说为
NULL
时的情况。
2.if(
NULL
== p){...} 或者 if(p ==
NULL
){...}
推荐前者因为这样更容易发现错误。
注:空
指针
,即首地址为0的
指针
,stdio.h中,
NULL
的定义为#define
NULL
0;
推荐使用方法1.
1.new异常的结果
在
C++
中,通过new分配内存时,假如内存不够,会根据编译器版本不同来处理异常,对于老的编译器,会返回
null
空
指针
(和malloc一样).但是目前大多数标准编译器都是直接抛出异常的.测试代码如下所示:
for (int i = 0 ; i<1000;i++) { // 不停new,直到new分配失败为止
double *ptr=new double[1000000];
cout<<"i ...