我正在处理基于自定义字符串类(String)的自定义向量(String_vector)。我的副本分配有问题,我认为我处于某种不会终止的循环中。在我的实现中return *this
如here所示,我实现了copy-and-swap方法。
String class:
class String{
public:
int len;
char *str;
String()
:len(0), str(nullptr){}
String(char const* S)
:len(strlen(S)), str(new char[len +1]){
assert(S != 0);
strcpy(str, S);
}
~String(){
delete[]str;
}
};
String_vector类:
class String_vector{
public:
String_vector(std::initializer_list<String>);
String* base = nullptr;
String* last = nullptr;
String* limit = nullptr;
String_vector(){};
String_vector(const String_vector& v){
reserve(v.size());
base = last;
last = uninitialized_copy(v.base, v.last, base);
}
//I think the issue is somewhere in here
String_vector& operator=(const String_vector & v){
String_vector p = v;
swap(*this, p);
return *this;
}
~String_vector(){
clear();
deallocate(base);
}
void clear(){
while(last > base){
(--last)->~String();
}
}
size_t size()const{
return last - base;
}
void swap(String_vector & v1, String_vector & v2){
std::swap(v1.base, v2.base);
std::swap(v1.last, v2.limit);
std::swap(v1.limit, v2.limit);
}
void reserve(std::size_t n){
if(!base){
base = allocate<String>(n);
last = base;
limit = n + base;
}else{
String* p = allocate<String>(n);
String* q = p;
for(String*i = base; i != last; ++i){
new(q)String(*i);
++q;
}
for(String*i = base; (i=last); ++i){
i ->~String();
}
deallocate<String>(base);
base = p;
last = q;
limit = base + n;
}
}
template<typename T>
inline T*
allocate(int n)
{
return reinterpret_cast<T*>(::operator new(n * sizeof(T)));
}
template<typename T>
inline void
deallocate(T* p)
{
::operator delete(p);
}
template<typename T, typename... Args>
inline T*
construct(T* p, Args&&... args)
{
return new (p) T(std::forward<Args>(args)...);
}
template<typename T>
inline void
destroy(T* p)
{
p->~T();
}
template<typename T>
inline T*
uninitialized_copy(T const* first, T const* last, T* out)
{
while (first != last) {
construct(out, *first);
++out;
++first;
}
return out;
}
size_t capacity()const{
return limit - base;
}
void push_back(String const & s){
if(!base){
reserve(8);
}else if(last == limit){
reserve(2*capacity());
}
construct(last++, s);
}
};
String_vector::String_vector(std::initializer_list<String> list)
: base(), last(), limit()
{
reserve(list.size());
for (String const& s : list)
push_back(s);
}
和主要:
int main()
{
String_vector v1 {"a", "b", "c"};
String_vector v2;
v2 = v1;
return 0;
}
谢谢!