您的位置:首页 > 编程语言 > C语言/C++

c++之内存分配、命名空间、强制类型转换学习总结

2020-08-02 20:36 471 查看

行业解决方案、产品招募中!想赚钱就来传!>>>


一、C++动态内存分配:

在学习c语言的时候,我们一般都是使用库函数malloc()来进行内存的申请分配,然后使用库函数free()来进行释放申请到的内存;现在在c++里面采用了另外一种内存申请的方法:

  • c++中通过new关键字进行动态内存申请。

  • C++中的动态内存申请是基于类型进行的。

  • delete关键字用于内存释放。

下面是申请内存的类型:

变量申请格式:


Type* pointer = new Type;

//

delete pointer



数组申请格式:


Type *pointer = new Type ;

//

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;
    in f97 t& 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、小结:

上面四种类型转换的例子,前三种把错误的地方给屏蔽掉,就是正确的例子,第四种类型转换,暂时继承的概念没有学到,所以这个例子不是很好。

同时内存分配的使用,本次也只是简单的说了一下概念,在真正实操当中,还是有很多要注意的地方,下期文章我们再详细解析。


本文分享自微信公众号 - TXP嵌入式(txp1121518wo-)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++