2013-10-02 101 views
0

我已經告訴給頭文件寫入到包含這個main.cpp輸出cout是感嘆號。 C++

OOP::array tab; 

    for(int i = 0; i < rand()%10 + 1; ++i) 
    { 
    tab.push_back(new BaseClass("BaseClass 1")); 
    tab.push_back(new BaseClass("BaseClass 2")); 
    tab.push_back(new BaseClass("BaseClass 3")); 
    } 

    OOP::print_tab_el(tab); //prints tab using operator<< for its elements. 

類陣列是用於智能指針的容器。 所以我實現了counted_ptr,BaseClassarray(我用std::vector作爲容器)類,但是當我調用「print_tab_el(tab)」函數時,我得到感嘆號!

似乎所有矢量的項目都是智能指針包含「!」作爲名字。我從來沒有把「!」那裏。

這是我的標題。

namespace OOP { 

    class BaseClass 
     { 
      public: 
       std::string name; 

       BaseClass(std::string arg) {name=arg;} 

       friend std::ostream & operator<<(std::ostream &os, const BaseClass& ref) 
        { 
         os<<ref.name<<"\n"; //gives ! ??? 
         return os; 
        } 

     }; 



    class array 
     { 
      public: 
       std::vector <counted_ptr<OOP::BaseClass> > myvec; 

       void push_back(OOP::BaseClass *arg) 
        { 
         counted_ptr< OOP::BaseClass> tmp(arg); 
         myvec.push_back(tmp); 

        } 

     }; 



    void print_tab_el(array arr) 
     { 

      std::vector <counted_ptr<OOP::BaseClass> >::iterator it; 

      for (it=arr.myvec.begin();it!=arr.myvec.end();++it){ 
       std::cout<<**it; 
       } 

     } 

}; 

這是程序的輸出:

! 
! 
! 
! 
! 
! 
! 
! 
and some more. 

新增:

counted_ptr.cpp

#ifndef COUNTED_PTR_CPP 
#define COUNTED_PTR_CPP 

#include "counted_ptr.h" 
#include <iostream> 

/****************************************************************************/ 
template <class T> 
counted_ptr<T>::counted_ptr(T* pointer):ptr(pointer) 
    { 
     refs.addRef(); 
    } 
/****************************************************************************/ 

template <class T> 
counted_ptr<T>::counted_ptr(const counted_ptr& ref):ptr(ref.ptr), refs(ref.refs+1) {} 
/****************************************************************************/ 

template <class T> 
counted_ptr<T>::~counted_ptr() 
    { 
     if (refs.takeRef()==0) 
      delete ptr; 
    } 
/****************************************************************************/ 

template <class T> 
T* counted_ptr<T>::operator->(){ 
    return ptr; 
} 
/****************************************************************************/ 

template <class T> 
T& counted_ptr<T>::operator*(){ 
    return *ptr; 
} 
/****************************************************************************/ 

template <class T> 
counted_ptr<T>& counted_ptr<T>::operator=(const counted_ptr<T>& rcpt_r){ 

    if (this!=&rcpt_r) 
     { 
      if (refs.takeRef()==0) 
       delete ptr; 

      ptr=rcpt_r.ptr; 
      //refs=rcpt_r.refs+1; 
      refs=rcpt_r.refs; 
      refs.addRef();  

     } 

    return *this; 
} 
/****************************************************************************/ 
#endif 

counted_ptr.h

#ifndef COUNTED_PTR_H 
#define COUNTED_PTR_H 

#include "reference.h" 
template <class T> 
class counted_ptr{ 

public: 
    counted_ptr(T* pointer); 
    counted_ptr(const counted_ptr& ref); 
    ~counted_ptr(); 

    T* operator->(); 
    T& operator*(); 
    counted_ptr& operator=(const counted_ptr<T>& ref); 


private: 
    T *ptr; 
    reference refs; 

}; 

class testclass{}; 
#endif 

#include "counted_ptr.cpp" 

reference.cpp

#include "reference.h" 
#include <iostream> 

/****************************************************************************/ 
reference::reference():nr_of_references(0){} 
/****************************************************************************/ 

reference::reference(const int value):nr_of_references(value){} 

reference& reference::operator=(const int& ref) 
    { 
     nr_of_references=ref; 
     return *this; 
    } 
/****************************************************************************/ 

reference::operator int()const 
    { 
     return nr_of_references; 
    } 
/****************************************************************************/ 

int reference::addRef() 
    { 
     return ++nr_of_references; 
    } 
/****************************************************************************/ 

int reference::takeRef() 
    { 
     return --nr_of_references; 
    } 
/****************************************************************************/ 

reference.h

class reference{ 
    public: 
     reference(); 
     reference(const int value); 
     //reference& operator=(const reference& ref); 
     reference& operator=(const int& ref); 
     operator int()const; 

     int addRef(); 
     int takeRef(); 

    private: 
     int nr_of_references; 

}; 
+0

我想我們需要看到一個更完整的例子(換句話說,你把什麼放到'myvec'中,例如? –

+0

用'C++ 11'shared_ptr'替換'counts_ptr',它對我來說工作正常所以我會說這個問題在'counts_ptr'中,無論如何。 –

+0

我不確定我是否理解你Mats,你能告訴我更多嗎? @David counting_ptr是基於計數引用的智能指針類。 – user2672883

回答

1

counted_ptr每個實例都有自己的reference實例。 reference的每個實例都有其自己的實例nr_of_references。雖然每個counter_ptr正確管理reference,但問題是隻有計數爲1的counted_ptr會在指針超出範圍時將其破壞,即使它被複制到不同的counted_ptr實例後。

您的counted_ptr需要重新設計,以便同一個對象的所有counted_ptr也操縱相同的reference

+0

這導致了這個問題創建一個指向同一對象的指針數組有什麼意義? –

+0

這是正確的,我現在可以看到它。 我創建的對象不使用new運算符,而是通過簡單地調用可能在堆上分配內存的構造函數。 這就是爲什麼當退出push_back功能時我會丟失對象。 非常感謝你們所有人。 – user2672883