C++知识点积累(2)

        1  若是出于某些缘由,须要在const成员函数中修改某一个或几个成员,那么能够将须要修改的成员声明为mutable,例如函数

  class A
  {
  public:
      int m_cannotBeModified;
      mutable int m_needToBeModified;
      void ModifyMutable() const
      {
          m_needToBeModified = 1;  //合法
          m_cannotBeModified = 1;  //不合法
      }
  };

        2  若是一个类没有显式声明构造函数,拷贝构造函数,赋值运算符,析构函数,编译器会相应地合成一个,若是类显式定      义了任何一个构造函数,包括拷贝构造函数,编译器就不会再合成构造函数。        
        3  要阻止一个类对象拷贝或赋值,能够声明一个简单的基类,基类中将拷贝构造函数和赋值运算符声明为private,这样其派生类的拷贝或赋值操做在编译期就能够被检查出来。例如:this

class A
{
protected:
    A(){}
    ~A(){}
private:
    A(const A& a){}
    A& operator=(const A&a){}
};
class B : public A
{
};
int main()
{
    B b;
    //B b1(b);                //编译不经过
    //B b2 = b;               //编译不经过
    B b3;
    //b3 = b;                 //编译不经过
    return 0;
}

        若是B不继承自任何类,直接把其拷贝构造函数和赋值运算符声明为private,并定义,那么类外不能作拷贝或赋值操做, 类内部或友元函数或友元类仍可作拷贝或赋值操做。
        若是B不继承自任何类,直接把其拷贝构造函数和赋值运算符声明为private,不提供定义,那么类外不能作拷贝或赋值操做,类内部或友元函数或友元类要作拷贝或赋值操做的话,连接期会发现错误,由于没有提供定义。
        4  若是在基类的构造函数中调用虚函数,那么虚函数毫不会降低到派生类阶层,调用的还是基类自己的虚函数,这时虚函数并无表现得像虚函数。派生类对象在基类构造期间,其对象类型就是基类,其运行时类型信息也属于基类,在进入派生类构造函数前毫不会成一个派生类对象。
        5  使用引用计数型智能指针shared_ptr能够有效管理资源,但若是使用shared_ptr时出现了环状引用,仍是会致使内存泄露例以下面的代码,程序退出后,new出来的A和new出来的B的引用计数都仍然是1,堆上的内存空间都不会释放。指针

class B;
class A
{
public:
  shared_ptr<B> m_b;
};
 
class B
{
public:
  shared_ptr<A> m_a;
};
 
int main()
{
  shared_ptr<A> a(new A);       //new出来的A的引用计数此时为1
  shared_ptr<B> b(new B);       //new出来的B的引用计数此时为1
  a->m_b = b;                   //B的引用计数增长为2
  b->m_a = a;                   //A的引用计数增长为2
}

         再例以下面的代码,主函数退出后,new出来的CCycleRef引用计数为1,内存没法释放:code

class CCycleRef  
{  
public:  
    ~CCycleRef()  
    {  
        cout <<"destroying CCycleRef"<<endl;  
    }  
  
public:  
    shared_ptr<CCycleRef> selfRef;  
};  
  
void CycleRefTest()  
{  
    shared_ptr<CCycleRef> cyclRef(new CCycleRef());  
    cyclRef->selfRef = cyclRef;   
}  
  
int _tmain(int argc, _TCHAR* argv[])  
{  
    CycleRefTest();  
    return 0;  
}

        解决办法是使用弱智能指针定义类中的智能指针成员,即将类中的shared_ptr换成weak_ptr便可。        
        6  前置自增运算符返回的是操做数加1后的值,返回的是操做数自己,是一个左值后置自增运算符返回的是操做数加1前的值,其操做数能够理解为值与原操做数相等的一个常量,是一个右值。
       重载前自增运算符和后自增运算符时,要保证其语义与全局的前自增运算符和后自增运算符的语义相同,即前自增返回一个左值,后自增返回一个右值。因此重载的前自增运算符一般返回该对象的引用,以支持++++obj这样的操做;重载的后自增运算符一般返回该类的一个常量对象,防止出现obj++++这样的操做。
       例以下面的代码:对象

class A
{
public:
    A(){ m_num = 0; }
    A& operator++()
    {
        ++m_num;
        return *this;
    }
    const A operator++(int i)
    {
        A temp(*this);
        ++*this;
        return temp;
    }

public:
    int m_num;
};

​
相关文章
相关标签/搜索