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

在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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值