我的 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__

5assert的妙用,(应该专题)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,类可以应用显式初始化列表,但是这样类的数据成员必须是公有,而且容易出错。

12   2008-7-30 关于操作符重载

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函数并正确地处理了零内存请求,就差不多了;如果内存释放程序又处理了空指针,那就没其他什么要做的了。至于在类成员版本的函数里增加继承支持,那将很快就可以完成。 

posted @ 2008-07-30 22:38  Conster康  阅读(413)  评论(0编辑  收藏  举报