声明表变量时未解析的外部符号

时间:2016-04-24 22:39:15

标签: c++ visual-studio-2013

我试图使用我的table1.h文件和我的table1.template文件,但每次我声明一个带有数据类型的表变量时我都会收到此错误

1>DataStructuresLab21V2.obj : error LNK2019: unresolved external symbol "public: __thiscall table<char>::table<char>(void)" (??0?$table@D@@QAE@XZ) referenced in function _wmain

我检查了拼写,我在头文件中声明了table()并在我的table1.template文件中实现,标题和模板文件之间的大小写正确。我不知道这个错误在我的代码中的位置,并且任何有助于识别出现错误的地方都会受到赞赏。编程语言是c ++,在Visual Studio 2013中完成。标题和模板文件由我的教授提供,用于修改文件以实现双重哈希。提前致谢

这是我的头文件table1.h

// FILE: table1.h (part of the namespace main_savitch_12A)
// TEMPLATE CLASS PROVIDED: table<RecordType> (a table of records with            keys).
//    This class is a container template class for a table of records.
//    The template parameter, RecordType, is the data type of the records in the
//    table. It may be any of the bulit-in C++ types (int, char, etc.), or a
//    class with a default constructor, an assignment operator, and an integer
//    member variable called key.
// 
// MEMBER CONSTANT for the table<RecordType> class:
//   static const size_type CAPACITY = ________
//     table<RecordType>::CAPACITY is the maximum number of records held by a table.
//
// CONSTRUCTOR for the table<RecordType> template class:
//   table( )
//     Postcondition: The table has been initialized as an empty table.
//
// MODIFICATION MEMBER FUNCTIONS for the table<RecordType> class:
//   void insert(const RecordType& entry)
//     Precondition: entry.key >= 0. Also if entry.key is not already a key in
//     the table, then the table has space for another record
//     (i.e., size( ) < CAPACITY).
//     Postcondition: If the table already had a record with a key equal to
//     entry.key, then that record is replaced by entry. Otherwise, entry has
//     been added as a new record of the table.
//
//   void remove(int key)
//     Postcondition: If a record was in the table with the specified key, then
//     that record has been removed; otherwise the table is unchanged.
//
// CONSTANT MEMBER FUNCTIONS for the table<RecordType> class:
//   bool is_present(const Item& target) const
//     Postcondition: The return value is true if there is a record in the
//     table with the specified key. Otherwise, the return value is false.
//
//   void find(int key, bool& found, RecordType& result) const
//     Postcondition: If a record is in the table with the specified key, then
//     found is true and result is set to a copy of the record with that key.
//     Otherwise found is false and the result contains garbage.
//
//    size_type size( ) const
//      Postcondition: Return value is the total number of records in the
//      table.
//
//  VALUE SEMANTICS for the table<RecordType> template class:
//    Assignments and the copy constructor may be used with table objects.

#ifndef TABLE1_H
#define TABLE1_H
#include <cstdlib>    // Provides size_t
using namespace std;

    template <class RecordType>
    class table
    {
    public:
        // MEMBER CONSTANT -- See Appendix E if this fails to compile.
        static const size_t CAPACITY = 811;
        // CONSTRUCTOR
        table();
        // MODIFICATION MEMBER FUNCTIONS
        void insert(const RecordType& entry);
        void remove(int key);
        // CONSTANT MEMBER FUNCTIONS
        bool is_present(int key) const;
        void find(int key, bool& found, RecordType& result) const;
        size_t size() const { return used; }
    private:
        // MEMBER CONSTANTS -- These are used in the key field of special      records.
        static const int NEVER_USED = -1;
        static const int PREVIOUSLY_USED = -2;
        // MEMBER VARIABLES
        RecordType data[CAPACITY];
        size_t used;
        // HELPER FUNCTIONS
        size_t hash(int key) const;
        size_t hash2(int key) const;
        size_t next_index(size_t index) const;
        void find_index(int key, bool& found, size_t& index) const;
        bool never_used(size_t index) const;
        bool is_vacant(size_t index) const;
    };


#endif

这是我的模板文件

#include "stdafx.h"
#include <cassert>
#include <cstdlib>
#include "table1.h"


using namespace std;

template<class RecordType>
size_t table<RecordType>::CAPACITY;

template <class RecordType>
const int table<RecordType>::NEVER_USED;

template <class RecordType>
const int table<RecordType>::PREVIOUSLY_USED;

template<class RecordType>
table<RecordType>::table()
{
    size_t i;
    used = 0;
    for (i = 0; i < CAPACITY; i++)
        data[i].key = NEVER_USED;
}

template<class RecordType>
void table<RecordType>::insert(const RecordType& entry)
{
    bool already_present;
    size_t index;

    assert(entry.key >= 0)

    find_index(entry.key, already_present, index);

    if (!already_present)
    {
        assert(size() < CAPACITY)
            index = hash(entry.key);
        while (!is_vacant(index))
            index = next_index(index);
        ++used;
        data[index] = entry;
    }
    else if (already_present)
    {
        assert(size() < CAPACITY)
            index = hash(entry.key) - hash2(entry.key);
        while (!is_vacant(index))
            index = next_index(index);
        ++used;
        data[index] = entry;
    }


}

template <class RecordType>
void table<RecordType>::remove(int key)
// Library facilities used: cassert
{
    bool found;        // True if key occurs somewhere in the table
    std::size_t index;   // Spot where data[index].key == key

    assert(key >= 0);

    find_index(key, found, index);
    if (found)
    {   // The key was found, so remove this record and reduce used by 1.
        data[index].key = PREVIOUSLY_USED; // Indicates a spot that's no longer in use.
        --used;
    }
}

template <class RecordType>
bool table<RecordType>::is_present(int key) const
// Library facilities used: assert.h
{
    bool found;
    std::size_t index;

    assert(key >= 0);

    find_index(key, found, index);
    return found;
}

template <class RecordType>
void table<RecordType>::find(int key, bool& found, RecordType& result) const
// Library facilities used: cassert.h
{
    size_t index;

    assert(key >= 0);

    find_index(key, found, index);
    if (found)
        result = data[index];
}

template <class RecordType>
inline size_t table<RecordType>::hash(int key) const
{
    return (key % CAPACITY);
}

template<class RecordType>
inline size_t table<RecordType>::hash2(int key) const
{
    return(key % hash(key));
}


template <class RecordType>
inline size_t table<RecordType>::next_index(size_t index) const
// Library facilities used: cstdlib
{
    return ((index + 1) % CAPACITY);
}

template <class RecordType>
void table<RecordType>::find_index(int key, bool& found, size_t& i) const
// Library facilities used: cstdlib
{
    size_t count; // Number of entries that have been examined

    count = 0;
    i = hash(key);
    while ((count < CAPACITY) && (data[i].key != NEVER_USED) && (data[i].key != key))
    {
        ++count;
        i = next_index(i);
    }
    found = (data[i].key == key);
}

template <class RecordType>
inline bool table<RecordType>::never_used(size_t index) const
{
    return (data[index].key == NEVER_USED);
}

template <class RecordType>
inline bool table<RecordType>::is_vacant(size_t index) const
{
    return (data[index].key == NEVER_USED) || (data[index].key == PREVIOUSLY_USED);
}

1 个答案:

答案 0 :(得分:0)

你的头文件中没有#include你的table1.template文件。

标头文件中#endif之前的最后一行必须为#include "table1.template"

例如:

        bool is_vacant(size_t index) const;
    };

#include "table1.template"

#endif

此外,您必须从模板文件中删除#include "table1.h"行:

#include "stdafx.h"
#include <cassert>
#include <cstdlib>
#include "table1.h"   //<-- Remove this line.

或者,您可以#include使用它们的#include "table1.h" #include "table1.template" #include "SomeType.h" // Other #include statements here. int main() { table<SomeType> myTable; // ...stuff... return 0 } 文件:

.template

模板类必须在使用模板时提供所有定义,因为<class RecordType>文件的内容不是以标准的.h / .cpp方式编译的。这是因为为您使用的每个不同#included定义了一个单独的类实例,因此在使用table<MyType>之前编译器需要.h文件和.template文件为var myVar = setInterval(myTimer, 5000); myDataGridPaginator = PF('myDatagridWidgetVar').getPaginator(); function myTimer() { myDataGridPaginator().setPage(myDataGridPaginator.cfg.page + 1); }