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;
};

​
相關文章
相關標籤/搜索