每日学习笔记(名字空间,new和delete)

来源:互联网 发布:三菱l系列plc编程手册 编辑:程序博客网 时间:2020/10/28 18:46

在C++中尽量用<iostream>而不用<stdio.h>

名字空间是管理标示符的一种方法,就是说在同一个名字空间下面只能访问这个名字空间内的标示符
简单的例子就是说比如说  
使用了#include   <iostream.h> 这个宏使用了以后所有 iostream.h 里面的定义的函宏 等等   表示都是在全局名字空间下面
(全局名字空间就是平时你使用的那个)
你写cout   cin等等常用的东西, 编译系统就能够找到相应的函数定义 而如果你使用了#include   <iostream> 相当于把所有iostream.h里面的标示符的定义都放在了std名字空间里面了,这个时候你使用cin , cout   编译器就找不到他们的定义了,必须使用   std::cin   或者   std::cout (或者在开头写上   using   namespace   std;) 
 

关键字namespace定义了一个名字空间,里面的变量和函数,声明在此名字空间外使用须在前面加名字空间名称.例如:

#include<iostream.h>namespace my{int a=3;}class test{public:int a;test(){a=1;}void fb(){int a=0;cout<<(my::a)<<(test::a)<<a;}};int main(){test t;t.fb();return 0;}

类名也可以做为此类的名字空间来使用,如要访问此类的成员(函数或变量)可用类名:成员名来实现,但要注意一些实例化问题,如:非静态成员不能在类外用类名:成员名来实现,如上面的例子中main函数换成

int main(){test::fb();return 0;}

提示报错.因为没有一个实例,也就是对象来调用这个函数

 (二)new和delete(部分摘自effective C++)

(1)new和delete的用法(转自http://www.cnblogs.com/jjzhou1988/archive/2008/11/30/1344314.html)

new用法:

          1.     开辟单变量地址空间

               1)new int;  //开辟一个存放数组的存储空间,返回一个指向该存储空间的地址.int *a = new int 即为将一个int类型的地址赋值给整型指针a. 

               2)int *a = new int(5) 作用同上,但是同时将整数赋值为5

          2.     开辟数组空间

               一维: int *a = new int[100];开辟一个大小为100的整型数组空间

               二维: int **a = new int[5][6]

               三维及其以上:依此类推.

         一般用法: new 类型 [初值]

delete用法:

          1. int *a = new int;

               delete a;   //释放单个int的空间

 (2)在C++中尽量使用new和delete而不使用malloc和free因为new和delete支持构造函数和析构函数而malloc和free不支持。另外new和delete必须成对使用,malloc和free必须成对使用!(当在C++中使用了智能指针:auto_ptr时除外)

(3) 下面的语句有什么错?

new的使用包含了两个步骤,首先内存被分配,然后被分配的内存调用一个或者多个构造函数。相应的delete也包含了两个步骤,首先为将被释放的内存调用一个或者多个析构函数,然后释放内存。

    string *stringArray = new string[100];    ...    delete stringArray;


虽然是一个new对应一个delete,但是stringArray 指向的 100 个string 对象中的99 个不会被正确地摧毁,因为他们的析构函数永远不会被调用。

此问题可以考虑为当我们用delete的时候是调用一个对象还是一个对象数组,显然上面的代码只是释放了一个对象,而不是一个对象数组,正确的代码如下:

    string *stringArray = new string[100];    ...    delete []stringArray;

 

4)析构函数里对指针调用delete

在每个构造函数里对指针进行初始化。对于一些构造函数,如果没有内存要分配给指针的话,指针要被初始化为0(即空指针)。  删除现有的内存,通过赋值操作符分配给指针新的内存。   在析构函数里删除指针。

 (5)事先准备好内存不够的情况

  那么,怎么办?如果想用一个很简单的出错处理方法,可以这么做:当内存分配请求不能满足时,调用你预先指定的一个出错处理函数。这个方法基于一个常规,即operator new不能满足请求时,会在抛出异常之前调用客户指定的一个出错处理函数——一般称为new-handler函数。

 指定出错处理函数时要用到 set_new_handler 函数,它在头文件<new>里大致是象下面这样定义的:

typedefvoid(*new_handler)();

new_handler set_new_handler(new_handler p) throw();

可以看到,new_handler 是一个自定义的函数指针类型,它指向一个没有输入参数也没有返回值的函数。set_new_handler 则是一个输入并返回new_handler类型的函数。

例:

voidnoMoreMemory()

{
 cerr << "Unable to satisfy request for memory\n";
  abort();
}
int main()
{
  set_new_handler(noMoreMemory);
  int *pBigDataArray = new int[100000000];
  ...
}

 

 假如operator new不能为100,000,000 个整数分配空间,noMoreMemory将会被调用,程序发出一条出错信息后终止。这就比简单地让系统内核产生错误信息来结束程序要好。

 (6) 写operator new和operator delete 时要遵循常规

当你要实现自己的内存管理方案或其它一些必要情况,那么就用运算符重载来对new 和delete重载,记住它们在C++中不是函数,而是操作符.

自己重写operate new时候必须要保证一下几点

1)有正确的返回值

2)可用内存不够要调用出错处理函数

3)处理好0字节请求的情况

考虑到以上几点,有关返回值的部分,如果内存分配成功,则返回指向已经被分配的内存的指针,如果内存分配失败,则应该调用出错处理函数,并指望该出错处理函数能够想办法去释放其它地方内存而使得operate new 最终能够分配到想要的内存,只有在出错处理函数为空的情况下operate new 才会抛出一个异常。另外C++标准要求,在请求分配0字节内存时候,operate new也要返回一个合法的指针(可以把它当作一字节的请求来处理)

非类成员形式的operator new的伪代码看起来会象下面这样:

void *operate new (size_t size)
{
 if(size == 0)
 {
  size=1;
 }
 while(1)  //分配size字节的内存
 {
  if(分配成功)
            return 指向内存的指针
  else                                //分配不成功,找出当前的出错处理函数
            new_handler globalHandler=set_new_handler(0); //通过对set_new_handler传入一个0参数找出出错处理函数为globalHanlder
            set_new_handler(globalHandler);
   
   if(globalHandler)
                 (*globalHandler)()
   else
                   throw std::bad_alloc();
  
    }
}

当在基类中写operate new 时,同时其还可能被子类继承,应该像下面这样写

void * Base::operator new(size_t size)
{
  if (size != sizeof(Base))             //  如果数量“错误”,让标准operate new去处理这个请求

        return ::operator new(size);        //                                        

  else...                                   //  否则处理这个请求
}

class Derived: public Base    
{                       
    Derived *p = new Derived;   

}

对于operate delete,情况要简单一些,记住C++保证删除空指针永远是安全的,

void operator delete(void *rawMemory)
{
  if (rawMemory == 0) return;                   ://如果指针为空,返回
  else                       

              释放rawMemory指向的内存;
  return;
}

 (7)使用operate的注意事项

1)避免隐藏标准形式的new  (内部范围的声明名称会隐藏掉外部范围的声明名称)

 2) 如果写了operator new就要同时写 operator delete