我的 c++的学习笔记(一)
1, char a[ ] = {'a', 'b', 'c'};
char b[ ] = {"abc"};
cout<<a<<endl;
cout<<strlen(a)<<endl;
cout<<b<<endl;
cout<<strlen(b)<<endl; 
  字符数组的两种初始化方式: 初始化列表(一定要以‘\0’结尾,否则结果意想不到),字符串字面值,编译器会自动添加‘\0’
2, const指针,指向const的指针,注意typedef之后的判断
Typedef string* pString;const pString cstr;  
则cstr就是const指针,而不是指向const的指针,相当于,string* const cstr
typedef的一些用法(应该专题)
3,printf(“\r”);表示的是回车,但是没有换行
4,一些宏的妙用: __LINE__ ,__FILE__ ,__FUNCTION__, __FILEW__, __FUNCTIONW__
5,assert的妙用,(应该专题)assert(p == NULL&& “what”);可以同时显示一字符串。
6,const成员必须在初始化列表中进行初始化,因为它不能被赋值,同引用
7,const int *pci = new const int(1024);1024是pci所指空间的立即初始化!
当然如果是个类类型,不显式初始化会调用默认构造函数。
8,delete表达式只能用在被new动态分配的内存和空指针上(因为不会出现大错)
9,auto_ptr类的使用 include<memory> 解释所有权的问题,get(),release(),reset();
10,void *area = operator new (sizeof CImage);
CImage *ptr = new (area) CImage(“清明上河图”);
但是这时候就要手动调用ptr的析构函数,然后调用delete删除这块指针。
11,类可以应用显式初始化列表,但是这样类的数据成员必须是公有,而且容易出错。
1  操作符首先要确定它的返回值是左值,还是右值,如果是左值 返回引用,如果是右值那就直接返回值;
2  +号等这样的操作符没有对象可以容纳改变后的值,对于这样的情况最好返回数值,否则只能要操作符体内创建临时对象用于容纳改变后的值,如果在堆中创建临时对象返回指针或者引用,在操作符函数体外还需要释放它,如果返回的对象而不是引用或者指针,那么效率是比较低的。如果返回的是数值,最好在该类的构造函数中增加对该类型数值的转换函数,如:返回值是int类型,那么最好有一个int类型作为参数的构造函数。
3  前自增和后自增:
在增量运算符中,放上一个整数形参,就是后增量运行符,它是值返回,对于前增量没有形参,而且是引用返回,
    Test &operator ++();   //前增量
Test &operator ++(int);//后增量
4除了对( )操作符外,对其他重载操作符提供缺省实参都是非法的;
13,自己重写operator new时,很重要的一点是函数提供的行为要和系统缺省的operator new一致。实际做起来也就是:要有正确的返回值;可用内存不够时要调用出错处理函数;处理好0字节内存请求的情况。此外,还要避免不小心隐藏了标准形式的new。
非类成员形式的operator new的伪代码: 
void * operator new(size_t size)        // operator new还可能有其它参数
{                                       
  if (size == 0)                      // 处理0字节请求时,
  { 
        size = 1;                            // 把它当作1个字节请求来处理
  }                                     
  while (1)
{
    分配size字节内存;
      if (分配成功)
           return (指向内存的指针);
    // 分配不成功,找出当前出错处理函数
      new_handler globalhandler = set_new_handler(0);  //
     set_new_handler(globalhandler); 
      if (globalhandler) (*globalhandler)();
      else throw std::bad_alloc();
  }
} 
为特定类写的new往往没有考虑该类被继承的情况,使用sizeof(父类)获得大小,但是如果发生子类调用父类的new时,往往 
会出错,子类的size往往大于父类的size。最好父类的new应该这么写: 
void * base::operator new(size_t size)
{
  if (size != sizeof(base))                  // 如果数量“错误”,让标准operator new,精华部分。
    return ::operator new(size);        // 去处理这个请求
                                                         // 
  ...                                                    // 否则处理这个请求
} 
对于operator delete(以及它的伙伴operator delete[]),情况更简单。所要记住的只是,c++保证删除空指针永远是安全的,所以你要充分地应用这一保证。
下面是非类成员形式的operator delete的伪代码:
void operator delete(void *rawmemory)
{
  if (rawmemory == 0) return;   //如果指针为空,返回
                                 // 
  释放rawmemory指向的内存; 
  return;
} 
  
这个函数的类成员版本也简单,只是还必须检查被删除的对象的大小。假设类的operator new将“错误”大小的分配请求转给::operator new,那么也必须将“错误”大小的删除请求转给::operator delete: 
void base::operator delete(void *rawmemory, size_t size)
{
  if (rawmemory == 0) return;          // 检查空指针 
  if (size != sizeof(base))                 // 如果size"错误",
{     
    ::operator delete(rawmemory);  // 让标准operator来处理请求
    return;                        
  }
  释放指向rawmemory的内存; 
  return;
} 
有关operator new和operator delete(以及他们的数组形式)的规定不是那么麻烦,重要的是必须遵守它。只要内存分配程序支持new-handler函数并正确地处理了零内存请求,就差不多了;如果内存释放程序又处理了空指针,那就没其他什么要做的了。至于在类成员版本的函数里增加继承支持,那将很快就可以完成。 
作者:康斯特
个人WIKI(常年更新):http://dev.wannaplay.cn/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
期待技术交流,共同进步
 
                    
                 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号