對於熟悉Accelerated C++一書的讀者,我正在編寫問題14-5的解決方案,並且遇到了一些有趣的行爲我無法解釋。加速C++ 14-5:自定義字符串類和引用計數器適用於一個構造函數,但不適用於另一個構造函數
問題涉及使用自定義字符串和指針/引用計數器類來實現一個程序,該程序可以連接字符串的向量並從中創建圖片。
從本質上講,有問題的程序的一部分如下:
int main()
{
vec<str> test;
str s;
while(getline(std::cin,s))
{
test.push_back(str(s.begin(),s.end()));
//test.push_back(s); // This line doesn't work here - why?
// Using the above line results in every str in test being
// the empty string
}
// Use the vec<str> to make pictures
}
它好像我引用計數器不能正常工作時,我使用註釋行:結果我得到的是彷彿test
中的每個str
都是空字符串。
這裏是我的getline
實現和str
和ptr
類的相關部分:
str
類:
class str
{
friend std::istream& getline(std::istream &is, str &s);
public:
typedef char* iterator;
typedef const char* const_iterator;
typedef size_t size_type;
str() : data(new vec<char>) { }
str(size_type n, char c) : data(new vec<char>(n,c)) { }
str(const char *cp) : data(new vec<char>)
{
std::copy(cp,cp+std::strlen(cp),std::back_inserter(*data));
}
template <class InputIterator>
str(InputIterator b, InputIterator e) : data(new vec<char>)
{
std::copy(b,e,std::back_inserter(*data));
}
// Other str member functions and operators
private:
ptr< vec<char> > data;
};
ptr
類:
template <class T>
class ptr
{
public:
void make_unique()
{
if(*refptr != 1)
{
--*refptr;
refptr = new std::size_t(1);
p = p ? clone(p) : 0;
}
}
ptr() : p(0), refptr(new std::size_t(1)) { }
ptr(T* t) : p(t), refptr(new std::size_t(1)) { }
ptr(const ptr &h) : p(h.p), refptr(h.refptr) { ++*refptr; }
ptr& operator=(const ptr &);
~ptr();
T& operator*() const
{
if(p)
{
return *p;
}
throw std::runtime_error("unbound ptr");
}
T* operator->() const
{
if(p)
{
return p;
}
throw std::runtime_error("unbound ptr");
}
private:
T* p;
std::size_t* refptr;
};
template <class T>
ptr<T>& ptr<T>::operator=(const ptr &rhs)
{
++*rhs.refptr;
// free the left hand side, destroying pointers if appropriate
if(--*refptr == 0)
{
delete refptr;
delete p;
}
// copy in values from the right-hand side
refptr = rhs.refptr;
p = rhs.p;
return *this;
}
template <class T>
ptr<T>::~ptr()
{
if(--*refptr == 0)
{
delete refptr;
delete p;
}
}
的vec
類基本上的子集0。如有必要,我也可以在這裏提供這些細節。
這裏是函數getline:
std::istream& getline(std::istream &is, str &s)
{
s.data->clear();
char c;
while(is.get(c))
{
if(c != '\n')
{
s.data->push_back(c);
}
else
{
break;
}
}
return is;
}
@BartoszKP如果數據已經有一些舊信息,我想先擺脫它,所以也許調用clear(),然後新的將是最好的?換句話說,我確實希望getline覆蓋s中發生的任何事情。 – Adam27X
@ Adam27X它不是「舊」的 - 它在'str'的其他實例中共享。你不想擺脫它。擺脫它是你的問題在這裏。如果參考計數器變爲「0」,'vec'將自動刪除。 – BartoszKP
@BartoszKP,你在哪裏得到getline的實現?我沒有看到它的例子,除非我是盲目的... –