关系到Vector<ElemType>::Vector(int capacity)
- C2143:语法错误:缺少“;” 在'<'之前
- C4430:缺少类型说明符 - 假定为 int。注意:C++ 不支持默认整数
- C2988:无法识别的模板声明/定义
- C2059:语法错误:'<'
关系到Vector<ElemType>::~Vector()
- C2588: '::~Vector' : 非法的全局析构函数
/*
* File: private/vector.cpp
* Last modified on Fri Jun 5 16:19:42 2009 by eroberts
* -----------------------------------------------------
* This file contains the implementation of the vector.h interface.
* Because of the way C++ compiles templates, this code must be
* available to the compiler when it reads the header file.
*/
#ifdef _vector_h
#include "stdafx.h"
/*
* Vector class implementation
* ---------------------------
* The Vector is internally managed as a dynamic array of elements.
* It tracks capacity (numAllocated) separately from size (numUsed).
* All access is bounds-checked for safety.
*/
template <typename ElemType>
Vector<ElemType>::Vector(int capacity) {
elements = new ElemType[capacity];
numAllocated = capacity;
numUsed = 0;
timestamp = 0L;
}
template <typename ElemType>
Vector<ElemType>::~Vector() {
if (elements != NULL) delete[] elements;
}
template <typename ElemType>
inline int Vector<ElemType>::size() {
return numUsed;
}
template <typename ElemType>
bool Vector<ElemType>::isEmpty() {
return size() == 0;
}
template <typename ElemType>
ElemType Vector<ElemType>::getAt(int index) {
checkRange(index, "getAt");
return elements[index];
}
template <typename ElemType>
void Vector<ElemType>::setAt(int index, ElemType elem) {
checkRange(index, "setAt");
elements[index] = elem;
}
/* Private method: checkRange
* --------------------------
* Verifies that index is in range for this vector, if not, raises an
* error. The verb string is used in the error message to describe the
* operation that caused the range error, .e.g "setAt" or "removeAt".
*/
template <typename ElemType>
inline void Vector<ElemType>::checkRange(int index, const char *verb) {
if (index < 0 || index >= size()) {
Error("Attempt to " + string(verb) + " index "
+ IntegerToString(index) + " in a vector of size "
+ IntegerToString(size()) + ".");
}
}
template <typename ElemType>
inline ElemType &Vector<ElemType>::operator[](int index) {
checkRange(index, "access");
return elements[index];
}
template <typename ElemType>
void Vector<ElemType>::add(ElemType elem) {
insertAt(numUsed, elem);
}
template <typename ElemType>
void Vector<ElemType>::insertAt(int index, ElemType elem) {
if (numAllocated == numUsed) enlargeCapacity();
if (index != numUsed) checkRange(index, "insertAt");
for (int i = numUsed; i > index; i--) {
elements[i] = elements[i-1];
}
elements[index] = elem;
numUsed++;
timestamp++;
}
template <typename ElemType>
void Vector<ElemType>::removeAt(int index) {
checkRange(index, "removeAt");
for (int i = index; i < numUsed-1; i++) {
elements[i] = elements[i+1];
}
numUsed--;
timestamp++;
}
template <typename ElemType>
void Vector<ElemType>::clear() {
delete[] elements;
elements = NULL;
numUsed = numAllocated = 0;
timestamp++;
}
template <typename ElemType>
const Vector<ElemType> &Vector<ElemType>::operator=(const Vector & rhs) {
if (this != &rhs) {
clear();
copyInternalData(rhs);
timestamp = 0L;
}
return *this;
}
template <typename ElemType>
Vector<ElemType>::Vector(const Vector & rhs) {
copyInternalData(rhs);
timestamp = 0L;
}
template <typename ElemType>
void Vector<ElemType>::mapAll(void (*fn)(ElemType)) {
long t0 = timestamp;
for (int i = 0; i < numUsed; i++) {
if (timestamp != t0) {
Error("Vector structure has been modified");
}
fn(elements[i]);
}
}
template <typename ElemType>
template <typename ClientDataType>
void Vector<ElemType>::mapAll(void (*fn)(ElemType, ClientDataType&),
ClientDataType & data) {
long t0 = timestamp;
for (int i = 0; i < numUsed; i++) {
if (timestamp != t0) {
Error("Vector structure has been modified");
}
fn(elements[i], data);
}
}
/*
* Vector::Iterator class implementation
* ----------------------------------
* The Iterator for Vector maintains a pointer to the original Vector and
* an index into that vector that identifies the next element to return.
*/
template <typename ElemType>
Vector<ElemType>::Iterator::Iterator() {
vp = NULL;
}
template <typename ElemType>
typename Vector<ElemType>::Iterator Vector<ElemType>::iterator() {
return Iterator(this);
}
template <typename ElemType>
Vector<ElemType>::Iterator::Iterator(Vector *vecRef) {
vp = vecRef;
curIndex = 0;
timestamp = vp->timestamp;
}
template <typename ElemType>
bool Vector<ElemType>::Iterator::hasNext() {
if (vp == NULL) Error("hasNext called on uninitialized iterator");
if (timestamp != vp->timestamp) {
Error("Vector structure has been modified");
}
return curIndex < vp->size();
}
template <typename ElemType>
ElemType Vector<ElemType>::Iterator::next() {
if (vp == NULL) Error("next called on uninitialized iterator");
if (!hasNext()) {
Error("Attempt to get next from iterator"
" where hasNext() is false");
}
return (*vp)[curIndex++];
}
template <typename ElemType>
ElemType Vector<ElemType>::foreachHook(FE_State & fe) {
if (fe.state == 0) fe.iter = new Iterator(this);
if (((Iterator *) fe.iter)->hasNext()) {
fe.state = 1;
return ((Iterator *) fe.iter)->next();
} else {
fe.state = 2;
return ElemType();
}
}
/* Private method: enlargeCapacity
* -------------------------------
* Doubles the current capacity of the vector's internal storage,
* copying all existing values.
*/
template <typename ElemType>
void Vector<ElemType>::enlargeCapacity() {
numAllocated = (numAllocated == 0 ? 10 : numAllocated*2);
ElemType *newArray = new ElemType[numAllocated];
for (int i = 0; i < numUsed; i++) {
newArray[i] = elements[i];
}
delete[] elements;
elements = newArray;
}
/* Private method: copyInternalData
* --------------------------------
* Common code factored out of the copy constructor and operator= to
* copy the contents from the other vector.
*/
template <typename ElemType>
void Vector<ElemType>::copyInternalData(const Vector & other) {
elements = new ElemType[other.numUsed];
for (int i = 0; i < other.numUsed; i++) {
elements[i] = other.elements[i];
}
numUsed = other.numUsed;
numAllocated = other.numUsed;
}
#endif
向量类定义示例
/*
* File: set.h
* Last modified on Thu Jun 11 09:17:43 2009 by eroberts
* modified on Tue Jan 2 14:34:06 2007 by zelenski
* -----------------------------------------------------
* This interface file contains the Set class template, a
* collection for efficiently storing a set of distinct elements.
*/
#ifndef _set_h
#define _set_h
#include "cmpfn.h"
#include "bst.h"
#include "vector.h"
#include "foreach.h"
/*
* Class: Set
* ----------
* This interface defines a class template that stores a collection of
* distinct elements, using a sorted relation on the elements to
* provide efficient managaement of the collection.
* For maximum generality, the Set is supplied as a class template.
* The element type is determined by the client. The client configures
* the set to hold values of a specific type, e.g. Set<int> or
* Set<studentT>. The one requirement on the element type is that the
* client must supply a comparison function that compares two elements
* (or be willing to use the default comparison function that uses
* the built-on operators < and ==).
*/
template <typename ElemType>
class Set {
public:
/* Forward references */
class Iterator;
/*
* Constructor: Set
* Usage: Set<int> set;
* Set<student> students(CompareStudentsById);
* Set<string> *sp = new Set<string>;
* -----------------------------------------
* The constructor initializes an empty set. The optional
* argument is a function pointer that is applied to
* two elements to determine their relative ordering. The
* comparison function should return 0 if the two elements
* are equal, a negative result if first is "less than" second,
* and a positive resut if first is "greater than" second. If
* no argument is supplied, the OperatorCmp template is used as
* a default, which applies the bulit-in < and == to the
* elements to determine ordering.
*/
Set(int (*cmpFn)(ElemType, ElemType) = OperatorCmp);
/*
* Destructor: ~Set
* Usage: delete sp;
* -----------------
* The destructor deallocates storage associated with set.
*/
~Set();
/*
* Method: size
* Usage: count = set.size();
* --------------------------
* This method returns the number of elements in this set.
*/
int size();
/*
* Method: isEmpty
* Usage: if (set.isEmpty())...
* ----------------------------
* This method returns true if this set contains no
* elements, false otherwise.
*/
bool isEmpty();
/*
* Method: add
* Usage: set.add(value);
* ----------------------
* This method adds an element to this set. If the
* value was already contained in the set, the existing entry is
* overwritten by the new copy, and the set's size is unchanged.
* Otherwise, the value is added and set's size increases by one.
*/
void add(ElemType elem);
/*
* Method: remove
* Usage: set.remove(value);
* -----------------------
* This method removes an element from this set. If the
* element was not contained in the set, the set is unchanged.
* Otherwise, the element is removed and the set's size decreases
* by one.
*/
void remove(ElemType elem);
/*
* Method: contains
* Usage: if (set.contains(value))...
* -----------------------------------
* Returns true if the element in this set, false otherwise.
*/
bool contains(ElemType elem);
/*
* Method: find
* Usage: eptr = set.find(elem);
* -----------------------------
* If the element is contained in this set, returns a pointer
* to that elem. The pointer allows you to update that element
* in place. If element is not contained in this set, NULL is
* returned.
*/
ElemType *find(ElemType elem);
/*
* Method: equals
* Usage: if (set.equals(set2)) . . .
* -----------------------------------
* This predicate function implements the equality relation
* on sets. It returns true if this set and set2 contain
* exactly the same elements, false otherwise.
*/
bool equals(Set & otherSet);
/*
* Method: isSubsetOf
* Usage: if (set.isSubsetOf(set2)) . . .
* --------------------------------------
* This predicate function implements the subset relation
* on sets. It returns true if all of the elements in this
* set are contained in set2. The set2 does not have to
* be a proper subset (that is, it may be equals).
*/
bool isSubsetOf(Set & otherSet);
/*
* Methods: unionWith, intersectWith, subtract
* Usage: set.unionWith(set2);
* set.intersectWith(set2);
* set.subtract(set2);
* -------------------------------
* These fmember unctions modify the receiver set as follows:
*
* set.unionWith(set2); Adds all elements from set2 to this set.
* set.intersectWith(set2); Removes any element not in set2 from this set.
* set.subtract(set2); Removes all element in set2 from this set.
*/
void unionWith(Set & otherSet);
void intersectWith(Set & otherSet);
void subtract(Set & otherSet);
/*
* Method: clear
* Usage: set.clear();
* -------------------
* This method removes all elements from this set. The
* set is made empty and will have size() = 0 after being cleared.
*/
void clear();
/*
* SPECIAL NOTE: mapping/iteration support
* ---------------------------------------
* The set supports both a mapping operation and an iterator which
* allow the client access to all elements one by one. In general,
* these are intended for _viewing_ elements and can behave
* unpredictably if you attempt to modify the set's contents during
* mapping/iteration.
*/
/*
* Method: mapAll
* Usage: set.mapAll(Print);
* -------------------------
* This method iterates through this set's contents
* and calls the function fn once for each element.
*/
void mapAll(void (*fn)(ElemType elem));
/*
* Method: mapAll
* Usage: set.mapAll(PrintToFile, outputStream);
* --------------------------------------------
* This method iterates through this set's contents
* and calls the function fn once for each element, passing
* the element and the client's data. That data can be of whatever
* type is needed for the client's callback.
*/
template <typename ClientDataType>
void mapAll(void (*fn)(ElemType elem, ClientDataType & data),
ClientDataType & data);
/*
* Method: iterator
* Usage: iter = set.iterator();
* -----------------------------
* This method creates an iterator that allows the client to
* iterate through the elements in this set. The elements are
* returned in the order determined by the comparison function.
*
* The idiomatic code for accessing elements using an iterator is
* to create the iterator from the collection and then enter a loop
* that calls next() while hasNext() is true, like this:
*
* Set<int>::Iterator iter = set.iterator();
* while (iter.hasNext()) {
* int value = iter.next();
* . . .
* }
*
* This pattern can be abbreviated to the following more readable form:
*
* foreach (int value in set) {
* . . .
* }
*
* To avoid exposing the details of the class, the definition of the
* Iterator class itself appears in the private/set.h file.
*/
Iterator iterator();
private:
#include "private/set.h"
};
#include "private/set.cpp"
#endif
此类Vector是库的标准组件,因此应该编译 - 直觉是缺少头文件或编译器设置错误。我从sourceforge CS106B 库中获得了这个副本
此外,这里是 vector.h 公共和私人文件
/*
* File: private/vector.h
* Last modified on Fri Jun 5 15:39:26 2009 by eroberts
* -----------------------------------------------------
* This file contains the private section of the vector.h interface.
* This portion of the class definition is taken out of the vector.h
* header so that the client need not have to see all of these
* details.
*/
public:
/*
* Class: Vector<ElemType>::Iterator
* ---------------------------------
* This interface defines a nested class within the Vector template that
* provides iterator access to the Vector contents.
*/
class Iterator : public FE_Iterator {
public:
Iterator();
bool hasNext();
ElemType next();
private:
Iterator(Vector *vecRef);
Vector *vp;
int curIndex;
long timestamp;
friend class Vector;
};
friend class Iterator;
ElemType foreachHook(FE_State & _fe);
/*
* Deep copying support
* --------------------
* This copy constructor and operator= are defined to make a
* deep copy, making it possible to pass/return vectors by value
* and assign from one vector to another. The entire contents of
* the vector, including all elements, are copied. Each vector
* element is copied from the original vector to the copy using
* assignment (operator=). Making copies is generally avoided
* because of the expense and thus, vectors are typically passed
* by reference, however, when a copy is needed, these operations
* are supported.
*/
const Vector & operator=(const Vector & rhs);
Vector(const Vector & rhs);
private:
ElemType *elements;
int numAllocated, numUsed;
long timestamp;
void checkRange(int index, const char *msg);
void enlargeCapacity();
void copyInternalData(const Vector & other);
和
/*
* File: vector.h
* Last modified on Fri Jun 5 15:35:35 2009 by eroberts
* modified on Tue Jan 2 13:56:15 2007 by zelenski
* -----------------------------------------------------
* This interface file contains the Vector class template, an
* efficient, safer, convenient replacement for the built-in array.
*/
#ifndef _vector_h
#define _vector_h
#include "genlib.h"
#include "strutils.h"
#include "foreach.h"
/*
* Class: Vector
* -------------
* This interface defines a class template that stores a homogeneous
* indexed collection. The basic operations are similar to those
* in the built-in array type, with the added features of dynamic
* memory management, bounds-checking on indexes, and convenient
* insert/remove operations. Like an array, but better!
* For maximum generality, the Vector is supplied as a class template.
* The client specializes the vector to hold values of a specific
* type, e.g. Vector<int> or Vector<studentT>, as needed
*/
template <typename ElemType>
class Vector {
public:
/* Forward references */
class Iterator;
/*
* Constructor: Vector
* Usage: Vector<int> vec;
* Vector<student> dormlist(200);
* Vector<string> *vp = new Vector<string>;
* -----------------------------------------------
* The constructor initializes a new empty vector. The optional
* argument is a hint about the expected number of elements that
* this vector will hold, which allows vector to configure itself
* for that capacity during initialization. If not specified,
* it is initialized with default capacity and grows as elements
* are added. Note that capacity does NOT mean size, a newly
* constructed vector always has size() = 0. A large starting
* capacity allows you to add that many elements without requiring
* any internal reallocation. The explicit keyword is required to
* avoid accidental construction of a vector from an int.
*/
explicit Vector(int sizeHint = 0);
/*
* Destructor: ~Vector
* Usage: delete vp;
* -----------------
* The destructor deallocates storage associated with this vector.
*/
~Vector();
/*
* Method: size
* Usage: nElems = vec.size();
* ---------------------------
* This method returns the number of elements in
* this vector.
*/
int size();
/*
* Method: isEmpty
* Usage: if (vec.isEmpty())...
* -----------------------------
* This method returns true if this vector contains no
* elements, false otherwise.
*/
bool isEmpty();
/*
* Method: getAt
* Usage: val = vec.getAt(3);
* --------------------------
* This method returns the element at the specified index
* in this vector. Elements are indexed starting from 0. A call to
* vec.getAt(0) returns the first element, vec.getAt(vec.size()-1)
* returns the last. Raises an error if index is outside the range
* [0, size()-1].
*/
ElemType getAt(int index);
/*
* Method: setAt
* Usage: vec.setAt(3, value);
* ---------------------------
* This method replaces the element at the specified index
* in this vector with a new value. The previous value at that
* index is overwritten with the new value. The size of the vector
* is unchanged. Raises an error if index is not within the
* range [0, size()-1].
*/
void setAt(int index, ElemType value);
/*
* Method: operator[]
* Usage: vec[0] = vec[1];
* -----------------------
* This method overloads [] to access elements from
* this vector. This allows the client to use array-like notation
* to get/set individual vector elements. Returns a reference to
* the element to allow in-place modification of values. Raises
* an error if index is not within the range [0, size()-1].
*/
ElemType & operator[](int index);
/*
* Method: add
* Usage: vec.add(value);
* ----------------------
* This method adds an element to the end of this vector.
* The vector's size increases by one.
*/
void add(ElemType elem);
/*
* Method: insertAt
* Usage: vec.insertAt(0, value);
* ------------------------------
* This method inserts the element into this vector at
* the specified index, shifting all subsequent elements one
* index higher. A call to vec.insertAt(0, val) inserts a new
* element at the beginning, vec.insertAt(vec.size(), val) add
* a new element to the end. The vector's size increases by one.
* Raises an error if index is outside the range [0, size()].
*/
void insertAt(int index, ElemType elem);
/*
* Method: removeAt
* Usage: vec.removeAt(3);
* -----------------------
* This method removes the element at the specified
* index from this vector, shifting all subsequent elements one
* index lower. A call to vec.removeAt(0) removes the first
* element, vec.removeAt(vec.size()-1), removes the last. The
* vector's size decreases by one. Raises an error if index is
* outside the range [0, size()-1].
*/
void removeAt(int index);
/*
* Method: clear
* Usage: vec.clear();
* -------------------
* This method removes all elements from this vector. The
* vector is made empty and will have size() = 0.
*/
void clear();
/*
* SPECIAL NOTE: mapping/iteration support
* ---------------------------------------
* The Vector class supports both a mapping operation and an iterator which
* allow the client access to all elements one by one. In general,
* these are intended for _viewing_ elements and can behave
* unpredictably if you attempt to modify the vector's contents during
* mapping/iteration.
*/
/*
* Method: mapAll
* Usage: vector.mapAll(Print);
* ----------------------------
* This method iterates through this vector's contents
* and calls the function fn once for each element.
*/
void mapAll(void (*fn)(ElemType elem));
/*
* Method: mapAll
* Usage: vector.mapAll(PrintToFile, outputStream);
* ------------------------------------------------
* This method iterates through this vector's contents
* and calls the function fn once for each element, passing
* the element and the client's data. That data can be of whatever
* type is needed for the client's callback.
*/
template <typename ClientDataType>
void mapAll(void (*fn)(ElemType elem, ClientDataType & data),
ClientDataType & data);
/*
* Method: iterator
* Usage: iter = vector.iterator();
* --------------------------------
* This method creates an iterator that allows the client to
* iterate through the elements in this vector. The elements are
* returned in index order.
*
* The idiomatic code for accessing elements using an iterator is
* to create the iterator from the collection and then enter a loop
* that calls next() while hasNext() is true, like this:
*
* Vector<int>::Iterator iter = vector.iterator();
* while (iter.hasNext()) {
* int elem = iter.next();
* . . .
* }
*
* This pattern can be abbreviated to the following more readable form:
*
* foreach (int elem in vector) {
* . . .
* }
*
* To avoid exposing the details of the class, the definition of the
* Iterator class itself appears in the private/vector.h file.
*/
Iterator iterator();
private:
#include "private/vector.h"
};
#include "private/vector.cpp"
#endif