I was bored one day, so I made this library:
template <class X, class Y> class HASH
{
public:
HASH(X element, Y key)
{
elements=new X[0];
keys=new Y[0];
keys[0]=key;
elements[0]=element;
num_elements=0;
};
~HASH ()
{
delete[] elements;
delete[] keys;
};
void Add(X element, Y key)
{
for (int x=0; x<=num_elements; x++)
{
if (keys[x]==key)
{
throw(key);
}
}
//make copy variables
X *copy_elements=new X[num_elements];
Y *copy_keys=new Y[num_elements];
//copy all the elements
for (int x=0; x<=num_elements; x++)
{
copy_elements[x]=elements[x];
copy_keys[x]=keys[x];
}
//delete the originals
delete[] elements;
delete[] keys;
//resize the originals
elements=new X[num_elements+1];
keys=new Y[num_elements+1];
//copy everything back to the originals
for (int x=0; x<=num_elements; x++)
{
elements[x]=copy_elements[x];
keys[x]=copy_keys[x];
}
//delete the copies
delete[] copy_keys;
delete[] copy_elements;
//increment num_elements
num_elements++;
//add the new elements
elements[num_elements]=element;
keys[num_elements]=key;
};
X operator [] (Y key)
{
int num=0;
for (int x=0; x<=num_elements; x++)
{
if (keys[x]==key)
{
num=x;
开发者_如何转开发 break;
}
}
return elements[num];
};
Y KeyNum(int x)
{
return keys[x];
};
int NumElements()
{
return num_elements;
};
private:
int num_elements;
X *elements;
Y *keys;
};
and then I tested it, and it worked. So now I am trying to create an experiment whose source code is this:
#include <hash.cpp>
#include <iostream>
using namespace std;
class OBJECT
{
public:
OBJECT(string name, int number)
{
int_properties=new HASH <string, int>;
};
~OBJECT()
{
delete int_properties;
};
HASH <string, int> *int_properties;
};
int main()
{
OBJECT a("name", 5);
return 0;
}
and it is returning the error:
brain.cpp: In constructor ‘OBJECT::OBJECT(std::string, int)’: brain.cpp:10: error: no matching function for call to ‘HASH<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int>::HASH()’ /usr/include/hash.cpp:4: note: candidates are: HASH<X, Y>::HASH(X, Y) [with X = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Y = int] /usr/include/hash.cpp:2: note: HASH<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int>::HASH(const HASH<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int>&)
I have made a whole lot of tests, and no matter what I do, I can't seem to initialize an object that is the data-member of another object. I just don't understand why.
You declare a constructor that takes parameters for HASH<X, Y>
:
HASH(X element, Y key)
{
elements=new X[0];
keys=new Y[0];
keys[0]=key;
elements[0]=element;
num_elements=0;
};
And then try to allocate HASH<string, int>
in OBJECT::OBJECT
:
OBJECT(string name, int number)
{
int_properties=new HASH <string, int>;
};
You just need to pass name
and number
to HASH<string, int>
's constructor:
int_properties=new HASH <string, int>(name, number);
brain.cpp: In constructor ‘OBJECT::OBJECT(std::string, int)’: brain.cpp:10: error: no matching function for call to ‘HASH, std::allocator >, int>::HASH()’
It's right. You haven't defined a default constructor for your HASH class.
There is no default constructor:
int_properties=new HASH <string, int>; // No constructor that takes zero arguments to HASH
There is no default constructor for your HASH class. Your constructor of OBJECT should be
OBJECT(string name, int number)
{
int_properties=new HASH <string, int>(name, number);
};
In C++ objects can certainly be data members of other objects. Otherwise you would only have classes composed of primitive types, and that would be of little use.
The problem here is that your class HASH
does not have a default constructor.
If you do not specify a constructor at all, then the compiler will create a deafault constructor for you. But as soon as you define a non-default constructor, the compiler will no longer supply a default one.
So either you have to pass an element and a key to the HASH
object that you are creating, or you have to give class HASH
a default constructor, that would presumably create an empty hash table.
int_properties = new HASH <string, int>;
This line attempts to call the default constructor of class HASH<string, int>
. That is, it tries to call a constructor with zero objects. But there is no such constructor. The constructor you defined is HASH<string, int>::HASH(string element, int key)
, which requires two arguments.
Template parameters appear in <>
. Function parameters appear in ()
. Don't confuse the two.
You can fix this either by using the constructor you defined by adding some function arguments:
int_properties = new HASH<string, int> (name, number);
or by modifying or overloading your constructor so that it can take zero arguments and be a default constructor.
template <class X, class Y> class HASH {
public:
HASH();
//...
};
template <class X, class Y> HASH<X,Y>::HASH() { /*...*/ }
HASH is a template class and you cannot instantiate it directly.
精彩评论