全部代码如下:
#include "../head.h"
#include <memory>
#include <utility>
class StrVec {
public:
StrVec() : elements(nullptr), first_free(nullptr), cap(nullptr) { }
StrVec(const StrVec&);
StrVec& operator=(const StrVec&);
~StrVec();
void push_back(const string&);
size_t size() const {return first_free - elements;}
size_t capacity() const {return cap - elements;}
string* begin() const {return elements;}
string* end() const {return first_free;}
private:
string *elements;
string *first_free;
string *cap;
static allocator<string> alloc;
void chk_n_alloc();
pair<string*, string*> alloc_n_copy(const string*, const string*);
void free();
void reallocate();
};
StrVec::StrVec(const StrVec &s) {
auto newdata = alloc_n_copy(s.begin(), s.end());
elements = newdata.first;
first_free = cap = newdata.second;
}
StrVec& StrVec::operator=(const StrVec &rhs) {
auto newdata = alloc_n_copy(rhs.begin(), rhs.end());
free();
elements = newdata.first;
first_free = cap = newdata.second;
return *this;
}
StrVec::~StrVec() {
free();
}
void StrVec::push_back(const string &s) {
chk_n_alloc();
alloc.construct(first_free++, s);
}
void StrVec::chk_n_alloc() {
if (size() == capacity()) reallocate();
}
pair<string*, string*> StrVec::alloc_n_copy(const string *b, const string *e) {
auto data = alloc.allocate(e - b);
return {data, uninitialized_copy(b, e, data)};
}
void StrVec::free() {
if (elements) {
for (auto p = first_free; p != elements; )
alloc.destroy(--p);
alloc.deallocate(elements, cap - elements);
}
}
void StrVec::reallocate() {
auto newcapacity = size() ? 2 * size() : 1;
auto newdata = alloc.allocate(newcapacity);
auto dest = newdata;
auto elem = elements;
for (size_t i = 0; i != size(); ++i)
alloc.construct(dest++, std::move(*elem++));
free();
elements = newdata;
first_free = dest;
cap = elements + newcapacity;
}
int main(int argc, char** argv) {
StrVec sv;
sv.push_back(string("hello"));
for (auto a : sv)
cout << a << endl;
return 0;
}
这是C++ primer书上13.5节的程序设计,实现类似
vector
对string
的管理
这套代码在编译时会有如下的报错:
/tmp/strvec-b2bd71.o:在函数‘StrVec::alloc_n_copy(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const*)’中:
strvec.cpp:(.text+0x94):对‘StrVec::alloc[abi:cxx11]’未定义的引用
/tmp/strvec-b2bd71.o:在函数‘StrVec::free()’中:
strvec.cpp:(.text+0x19d):对‘StrVec::alloc[abi:cxx11]’未定义的引用
strvec.cpp:(.text+0x1c3):对‘StrVec::alloc[abi:cxx11]’未定义的引用
/tmp/strvec-b2bd71.o:在函数‘StrVec::push_back(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)’中:
strvec.cpp:(.text+0x242):对‘StrVec::alloc[abi:cxx11]’未定义的引用
/tmp/strvec-b2bd71.o:在函数‘StrVec::reallocate()’中:
strvec.cpp:(.text+0x31f):对‘StrVec::alloc[abi:cxx11]’未定义的引用
/tmp/strvec-b2bd71.o:strvec.cpp:(.text+0x3a2): 跟着更多未定义的参考到 StrVec::alloc[abi:cxx11]
clang: error: linker command failed with exit code 1 (use -v to see invocation)
看这个报错可以大致猜到错误在
alloc
这个类对象上,在把static
去掉错误就没有了,书上有这个static
,第一不知道它为什么要加这个static
,第二不知道为什么加了以后会有这样的报错,现在还搞不懂,先做个记录。