2010-12-02 3 views
0

Ich war langweilig, ein Tag, so hatte ich diese Bibliothek:Warum kann ich Objekte in C++ nicht zu Datenelementen machen, die andere Objekte sind?

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; 
}; 

und dann habe ich getestet, und es funktionierte. So jetzt habe ich ein Experiment zu schaffen versuchen, dessen Quellcode ist dies:

#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; 
} 

und es gibt den Fehler:

 
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>&) 

ich eine ganze Menge Tests gemacht habe, und egal, was ich Ich kann anscheinend kein Objekt initialisieren, das das Datenelement eines anderen Objekts ist. Ich verstehe einfach nicht warum.

+4

Elemente = neu X [0]; Dies hat keine Größe. Sie können nicht auf X [0] zugreifen, es ist außerhalb der Grenzen –

+2

Nur als ein Tipp. Versuchen Sie, std :: vector <> für Ihre Elemente und Schlüssel zu verwenden. – pkit

+0

Was @Martin sagte. Obwohl "new T [n]" zulässig ist, wenn "n" gleich null ist, können Sie mit dem Ergebnis sehr wenig anfangen. – aschepler

Antwort

1
brain.cpp: In constructor ‘OBJECT::OBJECT(std::string, int)’: brain.cpp:10: error: no matching function for call to ‘HASH, std::allocator >, int>::HASH()’ 

Es ist richtig. Sie haben keinen Standardkonstruktor für Ihre HASH-Klasse definiert.

1

In C++ - Objekten können sicherlich Datenelemente anderer Objekte sein. Andernfalls hätten Sie nur Klassen, die aus primitiven Typen zusammengesetzt wären, und das wäre von geringem Nutzen. Das Problem besteht darin, dass Ihr class HASH keinen Standardkonstruktor hat.

Wenn Sie keinen Konstruktor angeben, erstellt der Compiler einen Deafault-Konstruktor für Sie. Sobald Sie jedoch einen nicht standardmäßigen Konstruktor definieren, liefert der Compiler keinen Standardkonstruktor mehr.

Also müssen Sie entweder ein Element und einen Schlüssel an das Objekt HASH übergeben, das Sie erstellen, oder Sie müssen class HASH einen Standardkonstruktor geben, der vermutlich eine leere Hashtabelle erstellen würde.

2

Sie deklarieren einen Konstruktor, der Parameter für HASH<X, Y> nimmt: zuzuteilen HASH<string, int> in OBJECT::OBJECT

HASH(X element, Y key) 
{ 
    elements=new X[0]; 
    keys=new Y[0]; 
    keys[0]=key; 
    elements[0]=element; 
    num_elements=0; 
}; 

Und dann versuchen:

OBJECT(string name, int number) 
{ 
    int_properties=new HASH <string, int>; 
}; 

Sie haben soeben name und number-HASH<string, int> ‚s Konstruktor übergeben müssen :

int_properties=new HASH <string, int>(name, number); 
+0

Es ist eine vollständige Antwort. –

+0

das Problem ist, dass es jetzt gibt mir einen Speicherfehler – noah

+1

@noah, das ist, weil Sie keinen Speicher für HASH-Mitglieder zuweisen. new int [0] gibt ein Array von null Elementen zurück. Ich bin mir nicht sicher, wie Sie "Schlüssel" oder "Elemente" entwickeln wollen, aber die Art, wie Sie es gerade tun, ist nicht korrekt. – MSN

0

HASH ist eine Vorlagenklasse und Sie können sie nicht direkt instanziieren.

+0

Was meinst du? Solange Sie die Vorlagenargumente angeben, muss ein standardkonformer Compiler sie instanziieren. – Dima

+1

Der Code wurde bearbeitet, dies ist nicht der Code, den ich gesehen habe: - / –

1

Es gibt keinen Standard-Konstruktor:

int_properties=new HASH <string, int>; // No constructor that takes zero arguments to HASH 
1

Es gibt keinen Standard-Konstruktor für Ihre HASH-Klasse. Ihr Konstruktor von OBJECT

OBJECT(string name, int number) 
{ 
    int_properties=new HASH <string, int>(name, number); 
}; 
1
int_properties = new HASH <string, int>; 

Diese Linie versucht, rufen Sie den Standardkonstruktor von class HASH<string, int> sein sollte. Das heißt, es versucht, einen Konstruktor mit null Objekten aufzurufen. Aber es gibt keinen solchen Konstruktor. Der Konstruktor, den Sie definierten, ist HASH<string, int>::HASH(string element, int key), der zwei Argumente erfordert.

Vorlagenparameter werden in angezeigt.Funktionsparameter erscheinen in (). Verwechsle die beiden nicht.

Sie können dies entweder beheben, indem Sie den Konstruktor verwenden Sie, indem Sie einige Funktionsargumente definiert:

int_properties = new HASH<string, int> (name, number); 

oder durch Änderung oder Konstruktor Überlastung, so dass es Null Argumente nehmen und einen Standardkonstruktor sein.

template <class X, class Y> class HASH { 
public: 
    HASH(); 
    //... 
}; 

template <class X, class Y> HASH<X,Y>::HASH() { /*...*/ } 
Verwandte Themen