LNK2019 errors in Driver.cpp

Pages: 12
The purpose of this assignment is to implement an ArrayDictionary.h file. Which is an array-based implementation of the ADT dictionary that organizes its data items in sorted search-key order. Search keys in the dictionary are unique. Right now I have two variables called entries and entryCount in the ArrayDictionary.cpp file that give errors saying identifier not found and undeclared identifier. Could anybody help me figure out why I keep getting these errors for these two variables. The code includes ArrayDictinary.h and ArrayDictionary.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
  @file ArrayDictionary.h */

#pragma once

  #ifndef _ARRAY_DICTIONARY
 #define _ARRAY_DICTIONARY

 #include "DictionaryInterface.h"
 #include "Entry.h"
 #include "NotFoundException.h"
#include "PrecondViolatedExcept.h"

template < class KeyType, class ValueType>
class ArrayDictionary : public DictionaryInterface < KeyType, ValueType>
{
private:
static const int DEFAULT_CAPACITY = 21; // Small capacity to test for
                                           // a full dictionary

Entry<KeyType, ValueType>* entries; // Array of dictionary entries
int entryCount;                    // Maximum capacity of the dictionary
void destroyDictionary();
int findEntryIndex(int firstIndex, int lastIndex, const KeyType & searchKey) const;
int maxEntries;

public:
ArrayDictionary();
ArrayDictionary(int maxNumberOfEntries);
ArrayDictionary(const ArrayDictionary<KeyType, ValueType>&dictionary);

virtual ~ArrayDictionary();

bool isEmpty() const;
int getNumberOfEntries() const;
bool add(const KeyType& searchKey, const ValueType& newValue) throw (PrecondViolatedExcep);
bool remove(const KeyType& searchKey);
void clear();
ValueType getValue(const KeyType& searchKey) const throw (NotFoundException);
bool contains(const KeyType& searchKey) const;
	
/** Traverses the items in this dictionary in sorted search-key order
 and calls a given client function once for each item. */
void traverse(void visit(ValueType&)) const;
}; // end ArrayDictionary

#include "ArrayDictionary.cpp"
#endif



// ArrayDictionary.cpp
#include <iostream>
#include "ArrayDictionary.h"
#include "PrecondViolatedExcept.h"

template < class KeyType, class ValueType>
void ArrayDictionary<KeyType, ValueType>::destroyDictionary()
{
	delete[] entries;

	entries = new Entry[maxEntries];

	entryCount = 0;
}

template < class KeyType, class ValueType>
inline int findEntryIndex(int firstIndex, int lastIndex, const KeyType& searchKey)
{
	int IndexMiddle = firstIndex + (lastIndex - firstIndex) / 2;

	if (firstIndex > lastIndex)

		return -1;

	else if (searchKey == entries[IndexMiddle].getKey())

		return IndexMiddle;

	else if (searchKey < entries[IndexMiddle].getKey())

		return findEntryIndex(firstIndex, IndexMiddle - 1, searchKey);

	else

		return findEntryIndex(IndexMiddle + 1, lastIndex, searchKey);

}

template < class KeyType, class ValueType>
inline ArrayDictionary<KeyType, ValueType>::ArrayDictionary() : entryCount(0), maxEntries(DEFAULT_CAPACITY)
{
	entries = new Entry[DEFAULT_CAPACITY];
}

template < class KeyType, class ValueType>
inline ArrayDictionary<KeyType,ValueType>::ArrayDictionary(int maxNumberOfEntries) :
	entryCount(0), maxEntries(maxNumberOfEntries)
{
	entries = new Entry[maxNumberOfEntries];
}


template < class KeyType, class ValueType>
inline ArrayDictionary<KeyType,ValueType>::ArrayDictionary(const ArrayDictionary& dictionary) :

	entryCount(dictionary.itemCount), maxEntries(dictionary.maxEntries)
{
	entries = new Entry[dictionary.maxEntries];

	for (int index = 0; index < dictionary.entryCount; index++)
	{
		entries[index] = dictionary.entries[index];
	}
}

template < class KeyType, class ValueType>

inline ArrayDictionary<KeyType, ValueType>::~ArrayDictionary()
{
	destroyDictionary();
}

template < class KeyType, class ValueType>
inline bool isEmpty()
{
	return (entryCount == 0);

}

template < class KeyType, class ValueType>
inline int getNumberOfEntries()
{
	return entryCount;
}

template < class KeyType, class ValueType>
inline void ArrayDictionary<KeyType, ValueType>:: clear()
{
	destroyDictionary();
}


template < class KeyType, class ValueType>
inline bool ArrayDictionary<KeyType, ValueType>::add(const KeyType& searchKey, const ValueType& newValue) throw (PrecondViolatedExcep)
{
	bool ableToInsert = (entryCount < maxEntries);

	if (ableToInsert)
	{
		// Make room for new entry by shifting all entries at
		// positions >= newPosition toward the end of the array
		// (no shift if newPosition == itemCount + 1). Performing
		// a binary search doesn’t help here, because we need to
		// shift the entries while looking for the insertion location.

		int index = entryCount;

		// Short-circuit evaluation is important

		while ((index > 0) && (searchKey < entries[index - 1].getKey()))
		{
			entries[index] = entries[index - 1];
			index--;
		}  // end while

		if (searchKey != entries[index - 1].getKey())
		{
			entries[index] = Entry<KeyType, ValueType>(searchKey, newValue);
			entryCount++;

		}
		else
		{
			auto message = "Attempt to add entry whose search key exits in dictionary.";
			throw (PrecondViolatedExcep(message);
		}

		return ableToInsert;
	}  // end add

}

template < class KeyType, class ValueType>
inline bool ArrayDictionary<KeyType, ValueType>:: remove(const const KeyType& itemKey)
{
	int currentIndex = findEntryIndex(0, entryCount - 1, itemKey);

	bool deletable = !isEmpty() && (currentIndex >= 0);

	if (deletable)
	{
		while (currentIndex < entryCount - 1)
		{
			entries[currentIndex] = items[currentIndex + 1];

			currentIndex++;
		}
		entryCount--;
	}
	return deletable;
}

template < class KeyType, class ValueType>
inline ValueType getValue(const KeyType& searchKey) throw(NotFoundException)
{
	int currentIndex = findEntryIndex(0, entryCount - 1, searchKey);

	if (currentIndex < 0)
		throw NotFoundException("nnItemis not in the Dictionary!nn");

	return entries[currentIndex].getItem();
}

template < class KeyType, class ValueType>
inline bool contains(const KeyType& searchKey) 
{
	return (findEntryIndex(0, entryCount - 1, itemKey) >= 0)
}

template < class KeyType, class ValueType>
inline void traverse(void visit(ValueType&))
{
	for (int itr = 0; itr < entryCount; itr++)
	{
		ValueType currentItem = entries[itr].getValue();

		visit(currentItem);
	}
}
Last edited on
First, you already do have an another thread about this issue: http://www.cplusplus.com/forum/beginner/278903/#msg1204476

Second, we cannot compile the code that you did post. Not even to the point where we would get errors that you see.

Please show the exact error messages and from which lines of your code do they come from. The compiler does mention a line number in each error message.
You can't put ArrayDictionary<KeyType, ValueType>:: in front of some member functions and not in front of others.
Don't be stupid!
My last post was getting too long. So I decided to post another one since I have revised this code so many times now.
The errors are on:
75 'entries' identifier not found
79 'entries' identifier not found
126 'entryCount' undeclared identifier
133 'entryCount' undeclared identifier

Also I have two errors saying '{' no matching tokens found: on lines 175 and 230.

Last edited on
Hello Lacy9265,

Is lines 67, 124 and 131 meant to be a class function or a regular function as it is written?

Andy
I was trying to have those use ArrayDictionary<KeyType, ValueType> like I do with the other functions but those gave me errors saying declaration is incompatible (E0147). As @dutch mention before you need to have all the functions use ArrayDictionary<KeyType, ValueType> I just kept getting errors saying declaration is incompatible (E0147) for those functions.
Last edited on
I have added ArrayDictionary<KeyType, ValueType> to all my functions. The errors I was getting before have disappeared however, new errors have shown up. Below this posted are listed the errors I have now.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#include <iostream>
#include "ArrayDictionary.h"
#include "PrecondViolatedExcept.h"

template < class KeyType, class ValueType>
inline void ArrayDictionary<KeyType, ValueType>::destroyDictionary()
{
	delete[] entries;

	entries = new Entry[maxEntries];

	entryCount = 0;
}

template < class KeyType, class ValueType>
inline int ArrayDictionary<KeyType, ValueType>::findEntryIndex(int firstIndex, int lastIndex, const KeyType& searchKey)
{
	int IndexMiddle = firstIndex + (lastIndex - firstIndex) / 2;

	if (firstIndex > lastIndex)

		return -1;

	else if (searchKey == entries[IndexMiddle].getKey())

		return IndexMiddle;

	else if (searchKey < entries[IndexMiddle].getKey())

		return findEntryIndex(firstIndex, IndexMiddle - 1, searchKey);

	else

		return findEntryIndex(IndexMiddle + 1, lastIndex, searchKey);

}

template < class KeyType, class ValueType>
inline ArrayDictionary<KeyType, ValueType>::ArrayDictionary() : entryCount(0), maxEntries(DEFAULT_CAPACITY)
{
	entries = new Entry[DEFAULT_CAPACITY];
}

template < class KeyType, class ValueType>
inline ArrayDictionary<KeyType,ValueType>::ArrayDictionary(int maxNumberOfEntries) :
	entryCount(0), maxEntries(maxNumberOfEntries)
{
	entries = new Entry[maxNumberOfEntries];
}


template < class KeyType, class ValueType>
inline ArrayDictionary<KeyType,ValueType>::ArrayDictionary(const ArrayDictionary& dictionary) :

	entryCount(dictionary.itemCount), maxEntries(dictionary.maxEntries)
{
	entries = new Entry[dictionary.maxEntries];

	for (int index = 0; index < dictionary.entryCount; index++)
	{
		entries[index] = dictionary.entries[index];
	}
}

template < class KeyType, class ValueType>

inline ArrayDictionary<KeyType, ValueType>::~ArrayDictionary()
{
	destroyDictionary();
}

template < class KeyType, class ValueType>
bool ArrayDictionary<KeyType, ValueType>:: isEmpty()
{
	return (entryCount == 0);

}

template < class KeyType, class ValueType>
inline int ArrayDictionary<KeyType, ValueType>::getNumberOfEntries()
{
	return entryCount;
}

template < class KeyType, class ValueType>
inline void ArrayDictionary<KeyType, ValueType>::clear()
{
	destroyDictionary();
}


template < class KeyType, class ValueType>
inline bool ArrayDictionary<KeyType, ValueType>::add(const KeyType& searchKey, const ValueType& newValue) throw (PrecondViolatedExcep)
{
	bool ableToInsert = (entryCount < maxEntries);

	if (ableToInsert)
	{
		// Make room for new entry by shifting all entries at
		// positions >= newPosition toward the end of the array
		// (no shift if newPosition == itemCount + 1). Performing
		// a binary search doesn’t help here, because we need to
		// shift the entries while looking for the insertion location.

		int index = entryCount;

		// Short-circuit evaluation is important

		while ((index > 0) && (searchKey < entries[index - 1].getKey()))
		{
			entries[index] = entries[index - 1];
			index--;
		}  // end while

		if (searchKey != entries[index - 1].getKey())
		{
			entries[index] = Entry<KeyType, ValueType>(searchKey, newValue);
			entryCount++;

		}
		else
		{
			auto message = "Attempt to add entry whose search key exits in dictionary.";
			throw (PrecondViolatedExcep(message);
		}

		return ableToInsert;
	}  // end add

}

template < class KeyType, class ValueType>
inline bool ArrayDictionary<KeyType, ValueType>::remove(const const KeyType& itemKey)
{
	int currentIndex = findEntryIndex(0, entryCount - 1, itemKey);

	bool deletable = !isEmpty() && (currentIndex >= 0);

	if (deletable)
	{
		while (currentIndex < entryCount - 1)
		{
			entries[currentIndex] = items[currentIndex + 1];

			currentIndex++;
		}
		entryCount--;
	}
	return deletable;
}

template < class KeyType, class ValueType>
inline ValueType getValue(const KeyType& searchKey) throw(NotFoundException)
{
	int currentIndex = findEntryIndex(0, entryCount - 1, searchKey);

	if (currentIndex < 0)
		throw NotFoundException("nnItemis not in the Dictionary!nn");

	return entries[currentIndex].getItem();
}

template < class KeyType, class ValueType>
inline bool ArrayDictionary<KeyType, ValueType>:: contains(const KeyType& searchKey)
{
	return (findEntryIndex(0, entryCount - 1, itemKey) >= 0)
}

template < class KeyType, class ValueType>
inline void ArrayDictionary<KeyType, ValueType>::traverse(void visit(ValueType&))
{
	for (int itr = 0; itr < entryCount; itr++)
	{
		ValueType currentItem = entries[itr].getValue();

		visit(currentItem);
	}
}
Last edited on
Errors:
L16: declaration is incompatible (E0147)
L17: ArrayDictionary<KeyType,ValueType> findIndex:: unable to match function definition to an existing declaration (C2244)

L73: declaration is incompatible (E0147)
L74: ArrayDictionary<KeyType,ValueType> isEmpty:: unable to match function definition to an existing declaration (C2244)

L80: declaration is incompatible (E0147)
L81: ArrayDictionary<KeyType,ValueType> getNumberEntries:: unable to match function definition to an existing declaration (C2244)

L164: declaration is incompatible (E0147)

L124 & L178: '{' no matching token found (C1075)

L170: declaration is incompatible (E0147)
I ctrl+F'd 'findIndex' - I don't see any definition of that.

isEmpty() - you declare it as
bool isEmpty() const;

but you are defining it as
1
2
3
4
5
6
template < class KeyType, class ValueType>
bool ArrayDictionary<KeyType, ValueType>:: isEmpty()
{
	return (entryCount == 0);

}

You need the 'const' specifier on the definition to match the declaration.
1
2
3
4
5
6
template < class KeyType, class ValueType>
bool ArrayDictionary<KeyType, ValueType>:: isEmpty() const
{
	return (entryCount == 0);

}


'getNumberEntries' - I don't see any definition of that.
1
2
3
4
5
6
7
8
9
10
11
12
13
template < class KeyType, class ValueType>
class ArrayDictionary : public DictionaryInterface < KeyType, ValueType>
{
  // ...
  bool isEmpty() const;
  // ...
};

template < class KeyType, class ValueType>
bool ArrayDictionary<KeyType, ValueType>:: isEmpty()
{
  // code
}

ArrayDictionary<KeyType,ValueType> isEmpty:: unable to match function definition to an existing declaration

True. There is no isEmpty() in the definition of the class ArrayDictionary. There is isEmpty() const though.
Is the code you posted your latest code, because it does not match your errors.


L16: declaration is incompatible (E0147)
L17: ArrayDictionary<KeyType,ValueType> findIndex:: unable to match function definition to an existing declaration (C2244)

You have a findEntryIndex, but no findIndex that I can see.


L73: declaration is incompatible (E0147)
L74: ArrayDictionary<KeyType,ValueType> isEmpty:: unable to match function definition to an existing declaration (C2244)

Your declaration is const. Your definition is not.


L80: declaration is incompatible (E0147)
L81: ArrayDictionary<KeyType,ValueType> getNumberEntries:: unable to match function definition to an existing declaration (C2244)

I can find no declaration or definition for getNumberEntries(). If it's in your base class, then you need to post the .h and .cpp files for the base class.


Thank you for your help guys. One last question I want to implement the functions from ArrayDictionary.cpp into a Driver.cpp. However when I do this I get an error saying //argument list for class template ArrayDictionary is missing. How would I put the template with ArrayDictionary. I have posted the Driver.cpp file below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include "ArrayDictionary.h"

int main() {

// Declare variables
	int userChoice;
	int key;
	int value;
    ArrayDictionary dictionary;  //argument list for class template ArrayDictionary is missing

    
    while (1) {
        std:: cout << "1.Insert element into the table" << std::endl;
        std::cout << "2.Search element from the key" << std::endl;
        std::cout << "3.Delete element at a key" << std::endl;
        std::cout << "4.Delete the entire dictionary" << std::endl;
        std::cout << "5.Exit" << std::endl;
        std::cout << "Enter your choice: ";
        std::cin >> userChoice;

    }

    switch(userChoice) {
    case 1:
        std::cout << "Enter element to be inserted: ";
        std::cin >> value;
        std::cout << "Enter key at which element to be inserted: ";
        std::cin >> key;
        dictionary.add(key, value);
        break;

    case 2:
        cout << "Enter key of the element to be searched: ";
        cin >> key;
        if (dictionary.getValue(key) == -1) {
            cout << "No element found at key " << key << endl;
 
        }
        else {
            cout << "Element at key " << key << " : ";
            cout << dictionary.getValue(key) << endl;
        }


    }
}
ArrayDictionary is a templated class. So for the default constructor you need to provide the two types for key and value.

 
ArrayDictionary<int, int> dictionary;

When I do that I get an error saying object of abstract class class type "ArrayDictionary <int, int>" is not allowed. Also when I added this in another error showed up saying 'ArrayDictionary <int, int> cannot instantiate abstract class.
Last edited on
ArrayDictionaryint,int> does not appear to be an abstract class if the listing of ArrayDistionary.h is current. It does however inherit from DictionaryInterface. Does DictionaryInterface (which you haven't shown) have any pure virtual functions that you haven't overloaded in ArrayDictionary<int,int>?
If ArrayDictionary is an abstract class (ie has at least one virtual function defined as = 0), you can't use it to define a variable. In this case you can only use a class derived from ArrayDictionary that has definition(s) for the base class function(s) defined as = 0 to define a variable.
Last edited on
@AbstractionAndy the DictionaryInterface.h file as all virtual functions. Here is the DictionaryInterface.h code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#pragma once
#ifndef _DICTIONARY_INTERFACE
#define _DICTIONARY_INTERFACE

#include "NotFoundException.h"

template<class KeyType, class ValueType>
class DictionaryInterface
{
public:
    
    // See if dictionary is empty
    // return true if empty, otherwise return false
    virtual bool isEmpty() const = 0;

   
    // Get the number of items in the dictionary
    virtual int getNumberOfItems() const = 0;

   
    // Inserts an value to dictionary according to the value's search key
    virtual bool add(const KeyType& searchKey, const ValueType& newValue) = 0;

  
    // Removes an value with a given search key from dictionary
    virtual bool remove(const KeyType& searchKey) = 0;

    // Removes all entries from this dictionary.
    virtual void clear() = 0;

    
    // Retrives a value with a given search key from a dictionary.
    virtual ValueType getValue(const KeyType& searchKey) const throw (NotFoundException) = 0;

    
    // See if the dictionary contains a value with a given search key
    virtual bool contains(const KeyType& searchKey) const = 0;

   
    // Traverses this dictionary and calls a given client function once for each value.
    virtual void traverse(void visit(ValueType&)) const = 0;


    virtual ~DictionaryInterface() {

    }
}; // end DictionaryInterface

#endif 
Is this still the definition of ArrayDictionary?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
template < class KeyType, class ValueType>
class ArrayDictionary : public DictionaryInterface < KeyType, ValueType>
{
private:
  static const int DEFAULT_CAPACITY = 21;
  Entry<KeyType, ValueType>* entries;
  int entryCount;
  int maxEntries;
  void destroyDictionary();
  int findEntryIndex( int, int, const KeyType & ) const;
public:
  ArrayDictionary();
  ArrayDictionary( int );
  ArrayDictionary( const ArrayDictionary<KeyType, ValueType>& );
  virtual ~ArrayDictionary();
  bool isEmpty() const;
  int getNumberOfEntries() const;
  bool add( const KeyType&, const ValueType& ) throw (PrecondViolatedExcep);
  bool remove( const KeyType& );
  void clear();
  ValueType getValue( const KeyType& ) const throw (NotFoundException);
  bool contains( const KeyType& ) const;
  void traverse( void visit(ValueType&) ) const;
};

Nothing in it looks to be abstract.

However, ArrayDictionary inherits DictionaryInterface. The error shows that DictionaryInterface is abstract and that ArrayDictionary lacks implementations for all pure abstract members of DictionaryInterface.
Yes the ArrayDictionary still looks like that @keskiverto. This is my first time working with a h file with all virtual methods. What do I call on then to get the functions.
Last edited on
Could I do instead of

 
ArrayDictionary<int,int> dictionary


do instead

1
2
3
DictionaryInterface<int,int> dictionary



Never tried doing this gave me the same error.
Last edited on
Pages: 12