[C++]链接错误:Undefined symbols for architecture x86_64

新手上路,请多包涵

问题描述

在完成C++ Primer上练习的时候,遇到了一个链接错误。

Undefined symbols for architecture x86_64:
"StrVec::alloc", referenced from:

  StrVec::alloc_n_copy(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const*, std::__1::basic_string<char,std::__1::char_traits<char>, std::__1::allocator<char> > const*) in StrVec-06a7bf.o
  StrVec::free() in StrVec-06a7bf.o
  StrVec::push_back(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in StrVec-06a7bf.o
  StrVec::push_back(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&) in StrVec-06a7bf.o
  StrVec::reallocate() in StrVec-06a7bf.o

ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

问题出现的平台版本及自己尝试过哪些方法

macOS mojave 10.14.1

初学者,暂时对于编译和链接的这些知识还没有深入学习,在google上看了很多类似的案例,都不能解决。

相关代码

// 请把代码文本粘贴到下方(请勿用图片代替代码)

Strvec.h:

#ifndef CP5_Strvec_h
#define CP5_Strvec_h

#include <string>
#include <memory>

class StrVec {
public: 
    StrVec() : 
        element(nullptr), first_free(nullptr), cap(nullptr) { }
    StrVec(const StrVec&);
    StrVec(StrVec&&) noexcept;
    StrVec& operator=(StrVec &&) noexcept;
    StrVec& operator=(const StrVec&);
    StrVec& operator=(std::initializer_list<std::string>);
    ~StrVec();

    void push_back(const std::string&);
    void push_back(std::string&&);

    size_t size()       const { return first_free - element; }
    size_t capacity()   const { return cap - element; }
    
    std::string *begin() const { return element; }
    std::string *end()   const { return first_free; }

private: 
    static std::allocator<std::string> alloc;
    std::string *element;
    std::string *first_free;
    std::string *cap;

    void free();
    void reallocate();
    void chk_n_alloc() { 
        if (size() == capacity())
            reallocate();
    }
    std::pair<std::string*, std::string*> alloc_n_copy(const std::string*, const std::string*);
};

#endif

Strvec.cpp

#include "StrVec.h"

StrVec::StrVec(const StrVec &rhs) {
    auto newdata = alloc_n_copy(rhs.begin(), rhs.end());
    element = newdata.first;
    first_free = cap = newdata.second;
}

StrVec::StrVec(StrVec &&rhs) noexcept
    : element(rhs.element), first_free(rhs.first_free), cap(rhs.cap) {
        rhs.element = rhs.first_free = rhs.cap = nullptr;
    } 

StrVec& StrVec::operator=(const StrVec &rhs) {
    auto data = alloc_n_copy(rhs.begin(), rhs.end());
    free();
    element = data.first;
    first_free = cap = data.second;
    return *this;
}

StrVec& StrVec::operator=(StrVec &&rhs) noexcept {
    if (this != &rhs)  {
        free();
        element = rhs.element;
        first_free = rhs.first_free;
        cap = rhs.cap;
        rhs.element = rhs.first_free = rhs.cap = nullptr;
    }
    return *this;
}

StrVec& StrVec::operator=(std::initializer_list<std::string> il) {
    auto data = alloc_n_copy(il.begin(), il.end());
    free();
    element = data.first;
    first_free = data.second;
    return *this;
}

StrVec::~StrVec() {
    free();
}

void StrVec::push_back(const std::string &s) {
    chk_n_alloc();
    alloc.construct(first_free++, s);
}

void StrVec::push_back(std::string &&s) {
    chk_n_alloc();
    alloc.construct(first_free++, std::move(s));
}

std::pair<std::string*, std::string*> StrVec::alloc_n_copy(const std::string *b, const std::string *e) {
    auto beg = alloc.allocate(e - b);
    auto end = std::uninitialized_copy(b, e, beg);
    return {beg, end};
}

void StrVec::free() {
    if (element) {
        for (auto p = first_free; p != element;)
            alloc.destroy(--p);
        alloc.deallocate(element, cap - element);
    }
}

void StrVec::reallocate() {
    auto newcapacity = size() ? 2 * size() : 1;
    auto newdata = alloc.allocate(newcapacity);
    auto dest = newdata;
    auto elem = element;
    for (size_t i = 0; i != size(); ++i) 
        alloc.construct(dest++, std::move(*elem++));
    free();
    element = newdata;
    first_free = dest;
    cap = element + newcapacity;
}

你期待的结果是什么?实际看到的错误信息又是什么?

能够正常编译运行

阅读 6.5k
1 个回答
✓ 已被采纳新手上路,请多包涵

已解决,原因是类的静态成员没有类外初始化

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题