C++ Primer第18章Vector的再实现及bug修正

C++Primer第18.1.2节在介绍allocator类的时候,给了一个仿照标准库中vector的例子。感觉示例代码非常好,但是本人发现了一个bug,与大家共享。

按照作者的示例程序,编译程序时总是在alloc.construct()函数处报错,不同IDE可能提示的错误原因不同,本人的是undefined reference to `Vector<std::string>::alloc‘。

仔细想想,应该与类Vector中alloc成员的静态属性有关,因此有两种修正方式:

 1)删去static关键字

 2)在全局作用域添加:template<class T> std::allocator<T> Vector<T>::alloc;

测试源代码如下:

 1 #include <iostream>
 2 #include <string>
 3 #include <memory>
 4 using namespace std;
 5
 6 std::ptrdiff_t max(std::ptrdiff_t a, std::ptrdiff_t b)
 7 {
 8     return a > b ? a : b;
 9 }
10
11 template <class T> class Vector{
12 public:
13     Vector(): elements(0), first_free(0), end(0) {}
14     void push_back(const T&);
15
16 private:
17     static std::allocator<T> alloc;
18     void reallocate();
19 public:
20     T * elements;
21     T * first_free;
22     T * end;
23 };
24
25 template<class T> std::allocator<T> Vector<T>::alloc;//如果没有这句,编译器报错,但如果类Vector中去掉static关键字,这句可以删掉
26
27 template <class T>
28 void Vector<T>::push_back(const T& t)
29 {
30     if(first_free == end)
31         reallocate();
32     alloc.construct(first_free,t);
33     ++first_free;
34 }
35
36 template <class T>
37 void Vector<T>::reallocate()
38 {
39     std::ptrdiff_t size = first_free - elements;
40     std::ptrdiff_t newcapacity = 2 * max(size, 1);
41
42     T * newelements = alloc.allocate(newcapacity);
43
44     uninitialized_copy(elements, first_free, newelements);
45
46     for(T * p = first_free; p != elements; alloc.destroy(--p));
47
48     if(elements)
49         alloc.deallocate(elements, end - elements);
50
51     elements = newelements;
52     first_free = elements + size;
53     end = elements + newcapacity;
54 }
55
56 int main()
57 {
58     Vector<string> str;
59     string s;
60     for(int i = 0; i < 5; ++i)
61     {
62         cin>>s;
63         str.push_back(s);
64     }
65     for(string * p = str.elements; p != str.first_free; ++p)
66         cout<<*p<<endl;
67     return 0;
68 }

虽然知道了解决办法,但是对于bug的原因并不是很清楚,欢迎大家留言交流及指教。

时间: 2024-08-14 15:33:48

C++ Primer第18章Vector的再实现及bug修正的相关文章

【C++ Primer 第18章】虚继承

学习资料 • C++学习20 虚基类详解 虚基类 多继承时很容易产生命名冲突,即使我们很小心地将所有类中的成员变量和成员函数都命名为不同的名字,命名冲突依然有可能发生,比如非常经典的菱形继承层次.如下图所示: 类A派生出类B和类C,类D继承自类B和类C,这个时候类A中的成员变量和成员函数继承到类D中变成了两份,一份来自 A-->B-->D 这一路,另一份来自 A-->C-->D 这一条路. 在一个派生类中保留间接基类的多份同名成员,虽然可以在不同的成员变量中分别存放不同的数据,但大

【C++ Primer 第七章】 构造函数再探、委托构造函数

构造函数初始值列表 1.  构造函数的初始值有时必不可少 • 有时我们可以忽略数据成员初始化和赋值之间的差异,但并非总能这样.如果成员时const或者是引用的话,必须将其初始化.类似的,当成员属于某种类类型且该类没有定义默认构造函数时,也必须将这个成员初始化. 例如: 1 class ConstRef 2 { 3 public: 4 ConstRef(int ii); 5 private: 6 int i; 7 const int ci; 8 int &ri; 9 }; 和其他常量对象或者引用一

C++primer第四章 数组和指针

4.1. 数组 数组是由类型名.标识符和维数组成的复合数据类型(第 2.5 节),类型名规定了存放在数组中的元素的类型,而维数则指定数组中包含的元素个数. 数组定义中的类型名可以是内置数据类型或类类型:除引用之外,数组元素的类型还可以是任意的复合类型.没有所有元素都是引用的数组. 4.1.1. 数组的定义和初始化 数组的维数必须用值大于等于 1 的常量表达式定义(第 2.7 节). 此常量表达式只能包含整型字面值常量.枚举常量(第 2.7 节)或者用常量表达式初始化的整型 const 对象. /

C++ Primer 学习笔记_74_面向对象编程 --再谈文本查询示例[续/习题]

面向对象编程 --再谈文本查询示例[续/习题] //P522 习题15.41 //1 in TextQuery.h #ifndef TEXTQUERY_H_INCLUDED #define TEXTQUERY_H_INCLUDED #include <iostream> #include <fstream> #include <sstream> #include <vector> #include <set> #include <map&g

《TCP/IP详解卷1:协议》第17、18章 TCP:传输控制协议(2)-读书笔记

章节回顾: <TCP/IP详解卷1:协议>第1章 概述-读书笔记 <TCP/IP详解卷1:协议>第2章 链路层-读书笔记 <TCP/IP详解卷1:协议>第3章 IP:网际协议(1)-读书笔记 <TCP/IP详解卷1:协议>第3章 IP:网际协议(2)-读书笔记 <TCP/IP详解卷1:协议>第4章 ARP:地址解析协议-读书笔记 <TCP/IP详解卷1:协议>第5章 RARP:逆地址解析协议-读书笔记 <TCP/IP详解卷1:协

《Cracking the Coding Interview》——第18章:难题——题目10

2014-04-29 04:22 题目:给定一堆长度都相等的单词,和起点.终点两个单词,请从这堆单词中寻找一条变换路径,把起点词变成终点词,要求每次变换只能改一个字母. 解法:Leetcode中有Word Ladder,这题基本思路一致. 代码: 1 // 18.10 Given a list of words, all of same length. Given a source and a destionation words, you have to check if there exis

《Cracking the Coding Interview》——第18章:难题——题目9

2014-04-29 04:18 题目:有一连串的数被读入,设计一个数据结构,能随时返回当前所有数的中位数. 解法:用一个大顶堆,一个小顶堆将数分成数量最接近的两份,就能轻松得到中位数了. 代码: 1 // 18.9 A stream of integers are passed to you, you have to tell me the median as they keep coming in. 2 #include <climits> 3 #include <iostream&

《Cracking the Coding Interview》——第18章:难题——题目13

2014-04-29 04:40 题目:给定一个字母组成的矩阵,和一个包含一堆单词的词典.请从矩阵中找出一个最大的子矩阵,使得从左到右每一行,从上到下每一列组成的单词都包含在词典中. 解法:O(n^3)级别的时间和空间进行动态规划.这道题目和第17章的最后一题很像,由于这题的时间复杂度实在是高,我动手写了字典树进行加速.如果单纯用哈希表来作为词典,查询效率实际会达到O(n)级别,导致最终的算法复杂度为O(n^4).用字典树则可以加速到O(n^3),因为对于一个字符串"abcd",只需要

《Cracking the Coding Interview》——第18章:难题——题目11

2014-04-29 04:30 题目:给定一个由'0'或者'1'构成的二维数组,找出一个四条边全部由'1'构成的正方形(矩形中间可以有'0'),使得矩形面积最大. 解法:用动态规划思想,记录二维数组每个元素向上下左右四个方向各有多少个连续的'1',然后用O(n^3)时间计算出满足条件的最大正方形.时间复杂度O(n^3),空间复杂度O(n^2). 代码: 1 // 18.11 Given an NxN matrix of 0s and 1s, find out a subsquare whose