设计类时static一个allocator类对象引发的问题

全部代码如下:

#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节的程序设计,实现类似vectorstring的管理

这套代码在编译时会有如下的报错:

/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去掉错误就没有了,这个问题的根源是什么现在还搞不懂,先做个记录。

猜你喜欢

转载自www.cnblogs.com/Anthony-ling/p/10894361.html