2013-03-26 20 views
7

Sono nuovo a c++ e ho difficoltà con il costruttore e le classi. Quindi, ecco il mio file di intestazione:non esiste un costruttore adatto per la conversione da "test *" a "test", costruttore,

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

    private: 
    string name; 
    int number; 

public: 

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

Questo è il file cpp:

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


test::test(){} 

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

ora, quando provo a chiamare

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

ottengo:

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

Quindi, qual è il problema con le classi che hanno * nel loro nome (ad esempio, le classi senza il file .cpp non hanno l'asterisco, tutte le altre lo fanno)? E cosa faccio di sbagliato?

risposta

21

Immagino che tu venga da uno sfondo Java/C#. t non è un tipo di riferimento qui, è un tipo di valore. new restituisce un puntatore a un oggetto. Quindi è necessario uno dei seguenti:

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

Se non sei ancora familiarità con i puntatori, quindi sicuramente non utilizzare l'ultima! Ma capire la semantica dei puntatori è abbastanza critico; Vi consiglio di leggere il capitolo relativo (s) nel tuo libro di testo ...

+0

Nizza, la risposta è molto migliore del mio :) +1 –

+0

tnx un sacco. hai indovinato, ho programmato in java e C# quindi sono un po 'in difficoltà con C++ :) .... – klo

+0

@klo Se provi a programmare C++ come hai programmato Java, farai molti errori. Non sono affatto simili. – john

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

deve essere

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

Così, che cosa è la cosa con le classi che hanno "*" nel loro nome

* viene utilizzato per indicare un puntatore, è non nel nome della classe. Ma è un argomento importante, quindi dovresti fare qualche ricerca su questo.

0

Lei non ha definito t come un puntatore:

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

O semplicemente

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

Quando è nuova usato in questa costruzione di oggetti, denota la creazione di un puntatore. Quello che stanno facendo è allocare dinamicamente la memoria che sono sicuro che non volevi fare. La costruzione oggetto Piuttosto, pila tipica allocata viene fatto semplicemente in questo modo:

T t; 

Anche se aveva destinato alla creazione di un puntatore e l'allocazione della memoria, l'avete fatto nel modo sbagliato. Un puntatore viene creato con il simbolo *, che mancava nel codice. In secondo luogo, quando hai finito di usare la memoria che hai creato, devi ricordarti di delete/delete[] il tuo codice. delete[] viene utilizzato su array allocati dinamicamente.Quindi questo è come sarebbe cercare il puntatore:

delete t; 
1

* non è parte del nome, è un modificatore che denota, che l'oggetto è un puntatore. Un puntatore è una variabile che tiene l'indirizzo in qualche punto della memoria, in cui è memorizzato l'oggetto reale. Alcuni principi fondamentali:

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

int * pI mezzi, che si desidera dichiarare un puntatore di inserire nella memoria, dove si svolge un int. &i significa che si desidera recuperare un puntatore alla variabile. Quindi ora pI detiene l'indirizzo in memoria, dove sono memorizzato. Ora è possibile dereference un puntatore - arrivare al valore del puntatore:

int j = *pI; 

Ora vi dico il compilatore, che dovrebbe andare all'indirizzo puntato da Pi e prelevare il suo contenuto (in quanto PI è un puntatore a int, il compilatore assumerà che ci sia un int lì).

Ora, torna al tuo esempio. new operatore alloca dinamicamente la memoria per un oggetto, quindi:

new test("rrr", 8); 

risultati in allocare una memoria per classe di test, chiamando il suo costruttore con parametri "RRR" e 8 e restituire un puntatore alla memoria allocata. Ecco perché non è possibile assegnarlo alla variabile test: il nuovo operatore in questo caso restituisce uno test *.

provare questo codice:

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

Così, che cosa è la cosa con le classi che hanno "*" nel loro nome (per esempio, le classi senza file cpp non hanno Asterix, tutti gli altri fanno) ?? ?

Hai sicuramente bisogno di conoscere i puntatori. test * e test sono due tipi completamente diversi in C++. Ecco due variabili con questi tipi:

test t; 
test* p; 

Qui, t è di tipo test, e p come tipo test*. Descriviamo test* come "puntatore a test".

Si può spesso pensare a un puntatore come all'indirizzo di memoria di un oggetto. Quindi in p, poiché è un puntatore, è possibile memorizzare l'indirizzo di memoria di t, che è un test. Per ottenere l'indirizzo di un oggetto, si usa il & operatore unario, in questo modo:

test t; 
test* p = &t; 

noti che tè un oggetto test. Non hai bisogno di dire new test(). Questo è dove C++ differisce da altri linguaggi che potresti aver usato, come C# e Java. Nel codice C++ sopra, t è un oggetto test.

Tuttavia, è possibile creare oggetti con new test(), qual è la differenza?

test t; crea un oggetto test con durata di archiviazione automatica. Ciò significa che viene distrutto alla fine del suo ambito (spesso la funzione viene dichiarata all'interno).

new test() crea un oggetto test con durata di archiviazione dinamica. Ciò significa che devi distruggere l'oggetto manualmente, altrimenti avrai una perdita di memoria. Questa espressione restituisce un puntatore e così si può inizializzare un oggetto di puntatore con esso:

test* p = new test(); 

Così ora diamo un'occhiata al vostro problema:

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

Ora sappiamo che new test("rrr", 8) restituisce un puntatore a test (un test*). Tuttavia, stai cercando di assegnarlo a un oggetto test. Semplicemente non puoi farlo. Uno di questi è un indirizzo e l'altro è un test. Quindi il compilatore dice "non esiste un costruttore adatto per convertire da test * a test". Ha senso ora, vero?

Invece, si consiglia di utilizzare la durata di archiviazione automatica. Usa solo new se davvero ne hai bisogno. Quindi, basta fare:

test t("rrr", 8); 
Problemi correlati