一、C++动态内存分配:
在学习c语言的时候,我们一般都是使用库函数malloc()来进行内存的申请分配,然后使用库函数free()来进行释放申请到的内存;现在在c++里面采用了另外一种内存申请的方法:
c++中通过new关键字进行动态内存申请。
C++中的动态内存申请是基于类型进行的。
delete关键字用于内存释放。
下面是申请内存的类型:
变量申请格式:
Type* pointer = new Type;
//
delete pointer
数组申请格式:
Type *pointer = new Type[N];
//
delete [] pointer;
下面我们来看一个例子:
#include <stdio.h>
int main()
{
int *p = new int;
*p=5;
*p=*p+10;
printf("p= %p\n",p);
printf("*p=%d\n",*p);
delete p;
p = new int[10];
for(int i=0;i<10;i++)
{
p[i]=i+1;
printf("p[%d] = %d\n",i,p[i]);
}
delete [] p;
return 0;
}
输出结果:
p= 0xb6d010
*p=15
p[0] = 1
p[1] = 2
p[2] = 3
p[3] = 4
p[4] = 5
p[5] = 6
p[6] = 7
p[7] = 8
p[8] = 9
p[9] = 10
二、new关键字与malloc函数的区别:
1、new关键字是C++的一部分。
2、malloc是由c库函数提供的。
3、new关键字以具体类型为单位进行内存分配。
4、malloc函数是以字节为单位进行内存分配。
5、new关键在申请单个类型变量时可以进行初始化。
6、malloc 不可以进行内存初始化。
我们来看使用new关键字是如何进行初始化的:
#include <stdio.h>
int main()
{
int * pi = new int(1);
float *pf = new float(2.0f);
char *pc = new char('c');
printf("*pi=%d\n",*pi);
printf("*pf=%f\n",*pf);
printf("*pc=%c\n",*pc);
delete pi;
delete pf;
delete pc;
return 0;
}
输出结果:
*pi=1
*pf=2.000000
*pc=c
三、c++ 中的命名空间:
在c语言中只有一个全局作用域:
c语言中所有的全局标识符共享同一个作用域。
标识符之间可能会发生冲突。-
c++中提出了命名空间的概念:
命名空间将全局作用域分成不同的部分。
不同命名空间中的标识符可以同名而且不会发生冲突。
命名空间可以相互嵌套。
全局作用域也叫默认命名空间。
1、下面我们来看一下c++中命名空间的定义:
namespace Name
{
namespace Internal
{
}
}
2、c++命名空间的使用:
使用整个命名空间:using namespace name;
使用命名空间中的变量:using name::variable;
使用默认命名空间中的变量:::variable;
3、代码示例:
#include <stdio.h>
namespace First
{
int i =0;
}
namespace Second
{
int i =1;
namespace Internal
{
struct Test
{
int x;
int y;
};
}
}
int main()
{
using namespace First;
using Second::Internal::Test;
printf("First::i is %d\n",i);
printf("Second::i is %d\n",Second::i);
Test i={2,4};
printf("i.x is %d\n",i.x);
printf("i.y is %d\n",i.y);
return 0;
}
输出结果:
First::i is 0
Second::i is 1
i.x is 2
i.y is 4
四、c++中的四种强制类型转换
强制类型转换类型汇总 | |
---|---|
static_cast | const_cast |
dynamic_cast | reinterpret_cast |
用法:xxx_cast(Expression)
下面是每种强制类型的具体讲解:
1、static_cast强制类型转换:
用于基本类型之间的转换
不能用于基本类型指针之间的转换
用于有继承关系类对象之间的转换和类指针之间的的转换
代码解析:
#include <stdio.h>
void static_cast_demo()
{
int i =55;
char c ='c';
int *pi =&i;
char *pc =&pc;
c=static_cast<char>(i);
pc=static_cast<char*>(pi);
}
int main()
{
static_cast_demo();
return 0;
}
输出结果:
t.cpp: In function ‘void static_cast_demo()’:
t.cpp:8:16: error: cannot convert ‘char**’ to ‘char*’ in initialization
char *pc =&pc;
^
t.cpp:11:29: error: invalid static_cast from type ‘int*’ to type ‘char*’
pc=static_cast<char*>(pi);
^
刚好验证了我们上面说的static_cast不能用在基本类型指针之间进行强制转换。
2、const_cast强制类型转换:
用于去除变量的只读属性
强制类型转换的目标类型必须是指针或者引用
代码解析:
#include <stdio.h>
void const_cast_demo()
{
const int& j =2;
int& k = const_cast<int&>(j);
const int x = 4;
int& y = const_cast<int&>(x);
int z = const_cast<int>(x);
k=8;
printf("k=%d\n",k);
printf("j=%d\n",j);
j =12;
printf("x=%d\n",x);
printf("y=%d\n",y);
printf("&x=%p\n",&x);
}
int main()
{
const_cast_demo();
return 0;
}
输出结果:
t.cpp: In function ‘void const_cast_demo()’:
t.cpp:11:30: error: invalid use of const_cast with type ‘int’, which is not a pointer, reference, nor a pointer-to-data-member type
int z = const_cast<int>(x);
^
t.cpp:18:6: error: assignment of read-only reference ‘j’
j =12;
通过上面的z转换,我们可以发现它的目标不是指针或者引用,所以报错。
3、reinterpret_cast强制类型转换:
用于指针类型之间的强制转换
用于整数和指针类型之间的强制转换
代码解析:
#include <stdio.h>
void reinterpret_cast_demo()
{
int i =2;
char c = 'c';
int *pi = &i;
char *pc =&c;
pc=reinterpret_cast<char*>(pi);
pi=reinterpret_cast<int*>(pc);
pi=reinterpret_cast<int*>(i);
c=reinterpret_cast<char(i);
}
int main()
{
reinterpret_cast_demo();
return 0;
}
输出结果:
t.cpp: In function ‘void reinterpret_cast_demo()’:
t.cpp:12:28: error: expected ‘>’ before ‘(’ token
c=reinterpret_cast<char(i);
^
t.cpp:12:30: error: invalid cast from type ‘int’ to type ‘char’
c=reinterpret_cast<char(i);
从结果我们可以看到,它用于整数之间的转换,不符合规则,所以报错。
4、dynamic_cast强制类型转换(暂时有些概念没有学到,先记住结论):
用于有继承关系的类指针之间的转换
用于有交叉关系的类指针之间的转换
具有类型检查的功能
需要虚函数的支持
代码分析:
#include <stdio.h>
void dynamic_cast_demo()
{
int i =2;
int *pi=&i;
char *pc =dynamic_cast<char*>(pi);
}
int main()
{
dynamic_cast_demo();
return 0;
}
输出结果:
.cpp: In function ‘void dynamic_cast_demo()’:
t.cpp:6:39: error: cannot dynamic_cast ‘pi’ (of type ‘int*’) to type ‘char*’ (target is not pointer or reference to class)
char *pc =dynamic_cast<char*>(pi);
不符合规则,所以报错。
5、小结:
上面四种类型转换的例子,前三种把错误的地方给屏蔽掉,就是正确的例子,第四种类型转换,暂时继承的概念没有学到,所以这个例子不是很好。
同时内存分配的使用,本次也只是简单的说了一下概念,在真正实操当中,还是有很多要注意的地方,下期文章我们再详细解析。