2013-03-26 6 views
7

Ich bin neu in c++ und ich habe Schwierigkeiten mit Konstruktor und Klassen. So, hier ist meine Header-Datei:kein geeigneter Konstruktor existiert, um von "test *" in "test" zu konvertieren, Konstruktor,

#pragma once 
#include <string> 
using namespace std; 
class test 
{ 

    private: 
    string name; 
    int number; 

public: 

    test(); 
    test(string i,int b); 
}; 

Dies ist CPP-Datei:

#include "test.h" 
#include <string> 
using namespace std; 


test::test(){} 

test::test(string i,int b){ 
    this->name=i; 
    this->number=b; 
} 

jetzt, wenn ich versuche,

zu nennen
test t=new test("rrr",8); 

ich:

1 IntelliSense: no suitable constructor exists to convert from "test *" to "test" 

Also, was ist die Sache mit Klassen mit * in ihrem Namen (zum Beispiel, Klassen ohne .cpp-Datei haben keine Asterix, alle anderen tun)? Und was mache ich falsch?

Antwort

21

Ich kann mir vorstellen, dass Sie von einem Java/C# Hintergrund kommen. t ist hier kein Referenztyp, es ist ein Werttyp. new gibt einen Zeiger auf ein Objekt zurück. Sie benötigen also eine der folgenden Möglichkeiten:

test t = test("rrr", 8); 
test t("rrr", 8); 
test *t = new test("rrr", 8); 

Wenn Sie mit Zeigern noch nicht vertraut sind, verwenden Sie definitiv nicht die letzte! Aber das Verständnis der Semantik von Zeigern ist ziemlich kritisch; Ich empfehle das entsprechende Kapitel (e) in Ihrem Lehrbuch zu lesen ...

+0

Schön, Ihre Antwort ist viel besser als meine :) +1 –

+0

tnx viel. Ich habe richtig geraten, ich habe in Java programmiert und C# so im ich etwas mit C++ zu kämpfen :) .... – klo

+0

@klo Wenn Sie versuchen, C++ zu programmieren, wie Sie Java programmiert haben, werden Sie viele Fehler machen. Sie sind sich überhaupt nicht sehr ähnlich. – john

2
test t=new test("rrr",8); 

müssen

// v 
test* t=new test("rrr",8); 

Also, was ist die Sache mit den Klassen "*" in ihrem Namen ist

* verwendet mit einem Zeiger, um anzuzeigen, ist es nicht im Namen der Klasse. Aber es ist ein großes Thema, also sollten Sie etwas darüber nachdenken.

0

Sie nicht t als Zeiger definiert haben:

test* t=new test("rrr",8); 

Oder

nur
test t = test("rrr",8); 
0
T* t = new T; 
//  ^^^ 

Wenn neu In dieser Objektkonstruktion bezeichnet es die Erstellung eines Zeigers. Was passiert, ist die dynamische Speicherzuweisung, die Sie sicher nicht machen wollten. Die Vielmehr typischer Stapel zugeordnet Objektbau ist einfach so gemacht:

T t; 

Auch wenn Sie auf die Schaffung eines Zeigers und die Zuweisung des Speichers bestimmt hatte, du hast es der falsche Weg. Ein Zeiger wird mit dem Symbol * erstellt, das in Ihrem Code fehlte. Zweitens, wenn Sie den von Ihnen erstellten Speicher nicht mehr benötigen, müssen Sie sich an delete/delete[] Ihren Code erinnern. delete[] wird für dynamisch zugewiesene Arrays verwendet.Also das ist, wie es für Ihre Zeiger aussehen:

delete t; 
1

* ist nicht Teil des Namens, es ist ein Modifikator bezeichnet, dass das Objekt ein Zeiger ist. Ein Zeiger ist eine Variable, die eine Adresse an einer Stelle im Speicher hält, an der das tatsächliche Objekt gespeichert ist. Einige Grundlagen:

int i = 5; 
int * pI = &i; 

int * pI bedeutet, dass Sie einen Zeiger erklären, in dem Speicher zu, wo ein int gehalten wird. &i bedeutet, dass Sie einen Zeiger auf Variable abrufen möchten. So hält nun pI die Adresse im Speicher, wo ich gespeichert bin. Jetzt können Sie dereferenzieren ein Zeiger - bekommen Wert des Zeigers:

int j = *pI; 

Nun sagen Sie den Compiler, dass es an die Adresse darauf von pI gehen sollte und dessen Inhalt retreive (seit pI ein Zeiger zu int, Compiler wird davon ausgehen, dass dort ein int ist).

Jetzt zurück zu Ihrem Beispiel. new Bediener ordnet Speicher dynamisch für ein Objekt, so:

new test("rrr", 8); 

Ergebnisse in einen Speicher für Testklasse Zuweisen Konstruktor mit Parametern „rrr“ und 8 Aufrufe und einen Zeiger auf zugewiesenen Speicher zurückkehrt. Deshalb können Sie sie nicht der Variablen test zuweisen: Der neue Operator gibt in diesem Fall eine test * zurück.

diesen Code Versuchen:

test * t = new test("rrr", 8); 
5

Also, was ist die Sache mit den Klassen "*" in ihrem Namen (zum Beispiel Klassen ohne CPP-Datei nicht haben asterix, alle anderen tun) ?? ?

Sie müssen auf jeden Fall über Zeiger lernen. test * und test sind zwei völlig verschiedene Typen in C++. Hier sind zwei Variablen mit diesen Typen:

test t; 
test* p; 

Hier t hat Typ test und p als Typ test*. Wir beschreiben test* als "Zeiger auf test".

Sie können sich einen Zeiger oft als die Speicheradresse eines Objekts vorstellen. So in , da es ein Zeiger ist, könnten wir die Speicheradresse t, die eine test ist. Um die Adresse eines Objekts zu erhalten, verwenden wir die einstellige & Operator, etwa so:

test t; 
test* p = &t; 

Beachten Sie, dass tist ein test Objekt. Sie müssen nicht new test() sagen. Hierunter unterscheidet sich C++ von anderen Sprachen, die Sie möglicherweise verwendet haben, wie C# und Java. In dem obigen C++ Code ist t ein test Objekt.

Sie können jedoch Objekte mit new test() erstellen, also was ist der Unterschied?

test t; erstellt ein test Objekt mit automatischer Speicherdauer. Dies bedeutet, dass es am Ende seines Gültigkeitsbereichs zerstört wird (oft wird die Funktion innerhalb deklariert).

new test() erstellt ein Objekt test mit dynamischer Speicherdauer. Das bedeutet, dass Sie das Objekt manuell zerstören müssen, da sonst ein Speicherleck entsteht. Dieser Ausdruck gibt einen Zeiger und so kann man einen Zeiger Objekt mit ihm initialisieren:

test* p = new test(); 

So, jetzt lassen Sie sich auf Ihrem Problem aussehen:

test t=new test("rrr",8); 

Wir wissen jetzt, dass new test("rrr", 8) einen Zeiger auf test zurückgibt (a test*). Sie versuchen jedoch, es einem Objekt test zuzuweisen. Du kannst das einfach nicht tun. Einer von ihnen ist eine Adresse und der andere ist ein test. Daher sagt der Compiler, dass "kein geeigneter Konstruktor zum Konvertieren von test * zu test existiert". Macht jetzt Sinn, oder?

Stattdessen sollten Sie die automatische Speicherdauer bevorzugen. Verwenden Sie nur new, wenn Sie wirklich brauchen. Also einfach: