|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Sep 2004
Città: Bolzano
Messaggi: 2156
|
[C++] Utilizzo di classe
Premetto che so programmare in Java. Java mi permette di istanziare classi scritte da me in un altra classe. Per spiegare vi faccio un breve esempio:
Prima classe/primo file: Codice:
public class ClasseA{ //variabili //costruttore //metodi } Codice:
public class Main{ public static void main(String[] args){ ClasseA = new ClasseA(); } Codice:
#include <iostream> #include <stdlib.h> #include <time.h> using namespace std; class Book { string title; string author; int price; public: Book(string, string, int); void printBook(); void printBookPrice(); string getTitle(); string getAuthor(); int getPrice(); void setPrice(int); }; Book::Book(string newTitle, string newAuthor, int newPrice) { title = newTitle; author = newAuthor; price = newPrice; } void Book::printBook() { cout << "The title of the book is: " << title << ".\n"; cout << "The Author of the book is: " << author << ".\n"; } void Book::printBookPrice() { cout << "Title: " << title << ". Author: " << author << ". Price: " << price << "\n"; } string Book::getTitle() { return title; } string Book::getAuthor() { return author; } int Book::getPrice() { return price; } void Book::setPrice(int newPrice) { price = newPrice; }
__________________
Vendo...nulla. Cerco...la felicità. |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Oct 2005
Messaggi: 3306
|
Per prima cosa sposta la dichiarazione della classe Book in un file header Book.h (usa #pragma once all'inizio del file per evitare problemi con inclusioni multiple che altrimenti vengono sicuramente fuori) e l'implementazione la metti in Book.cpp che include Book.h oltre agli #include che hai già messo.
using namespace std lo metti in Book.cpp, mentre in Book.h espliciti il namespace, nel tuo caso basta usare std::string. Per usare a questo punto la classe Book non dovrai fare altro che includere Book.h ovunque tu voglia usarla. Book.h: Codice:
#pragma once #include <string> class Book { std::string title; std::string author; int price; public: //meglio usare: //Book(const std::string &, const std::string &, int); Book(std::string, std::string, int); void printBook(); void printBookPrice(); //meglio usare: //const std::string & getTitle() const; std::string getTitle(); std::string getAuthor(); int getPrice(); void setPrice(int); }; Codice:
#include <iostream> #include <stdlib.h> #include <time.h> #include <Book.h> using namespace std; Book::Book(string newTitle, string newAuthor, int newPrice) { title = newTitle; author = newAuthor; price = newPrice; } void Book::printBook() { cout << "The title of the book is: " << title << ".\n"; cout << "The Author of the book is: " << author << ".\n"; } void Book::printBookPrice() { cout << "Title: " << title << ". Author: " << author << ". Price: " << price << "\n"; } //meglio usare: //const string & Book::getTitle() const string Book::getTitle() { return title; } string Book::getAuthor() { return author; } int Book::getPrice() { return price; } void Book::setPrice(int newPrice) { price = newPrice; } Inoltre per i metodi get è bene specificare l'attributo const per indicare che tali metodi non modificano la classe e che possono essere utilizzati da riferimenti const. Poi ci sarebbero un pò di dettagli mancanti, come l'utilizzo del costruttore di copia ecc... |
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Sep 2004
Città: Bolzano
Messaggi: 2156
|
Grazie della risposta celere.
il "# pragma" non ò'avevo mai visto ne letto. Il "const" lo avevo gia notato in giro nei codici, ma non ho capito esattamente a cosa serve.
__________________
Vendo...nulla. Cerco...la felicità. |
![]() |
![]() |
![]() |
#4 | |
Senior Member
Iscritto dal: Oct 2005
Messaggi: 3306
|
Quote:
Ad esempio se usassi la tua classe Book un codice del genere: Codice:
const Book & book = GetBook(); string title = book.getTitle(); In C++ si parla di "const correctness" |
|
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Sep 2004
Città: Bolzano
Messaggi: 2156
|
Correggimi se sbaglio. In java basta che scrivo una classe, e posso riusarla dove voglio. In C++ devo sempre scrivere un file h e uno cpp?
__________________
Vendo...nulla. Cerco...la felicità. |
![]() |
![]() |
![]() |
#6 |
Senior Member
Iscritto dal: Oct 2005
Messaggi: 3306
|
|
![]() |
![]() |
![]() |
#7 |
Senior Member
Iscritto dal: Sep 2004
Città: Bolzano
Messaggi: 2156
|
OK, perfetto. Proverò a programmare un pò....comunque devo prima andare a studiarmi sta cosa del "const" che non ho capito l'utilizzo.
Grazie.
__________________
Vendo...nulla. Cerco...la felicità. |
![]() |
![]() |
![]() |
#8 | |
Senior Member
Iscritto dal: Sep 2004
Città: Bolzano
Messaggi: 2156
|
Quote:
__________________
Vendo...nulla. Cerco...la felicità. |
|
![]() |
![]() |
![]() |
#9 | |
Senior Member
Iscritto dal: Oct 2005
Messaggi: 3306
|
Quote:
Per il passaggio di oggetti in C++ è buona norma usare i riferimenti per motivi di performance (per i puntatori si apre un discorso a parte, ma lasciamolo perdere per il momento). Nel tuo caso quando chiami il costruttore crei una copia delle stringhe, mentre se usi il riferimento no. Con il riferimento nasce un problema però: te puoi modificare l'oggetto passato potenzialmente creando problemi al chiamante, pertanto si usa il modificatore const. In questo modo il chiamante sa che la tua classe non modificherà l'oggetto e contemporaneamente la tua classe non modificherà l'oggetto nemmeno per sbaglio. In ultimo i vantaggi prestazionali. Sempre per il solito motivo che è bene passare gli oggetti per riferimento e per il fatto che è bene che siano pure const per i motivi sopra elencati, se non hai specificato dei metodi come const non puoi utilizzare l'oggetto. Metti ad esempio che tu voglia modellare una libreria e tu abbia un metodo AddBook (l'implementazione è tarata sull'esempio): Codice:
map<string, Book> books; void Library::AddBook(const Book & book) { map[book.getTitle()] = book; } |
|
![]() |
![]() |
![]() |
#10 |
Senior Member
Iscritto dal: Sep 2004
Città: Bolzano
Messaggi: 2156
|
OK, tutto sommato ho capito.
Diciamo che il punto è se uso il passaggio by reference o meno. Ma usando il costruttore come ho fatto io, in pratica creando copie di stringhe, a parte le prestazioni ho altri svantaggi?
__________________
Vendo...nulla. Cerco...la felicità. |
![]() |
![]() |
![]() |
#11 |
Senior Member
Iscritto dal: Sep 2004
Città: Bolzano
Messaggi: 2156
|
....noto solo ora che facendo copia incolla del codice scritto da te, Book.cpp e Book.h, mi da errore su #include <Book.h> dicendo No such file or directory.
EDIT facendo #include "Book.h" funziona.
__________________
Vendo...nulla. Cerco...la felicità. Ultima modifica di Emaborsa : 17-02-2011 alle 15:48. |
![]() |
![]() |
![]() |
#12 |
Senior Member
Iscritto dal: Apr 2010
Città: Frosinone
Messaggi: 416
|
in realtà è anche una questione semantica.. se un metodo non modifica l'oggetto (come può essere un getter) allora dovrebbe essere dichiarato const
|
![]() |
![]() |
![]() |
#13 | |
Senior Member
Iscritto dal: Sep 2004
Città: Bolzano
Messaggi: 2156
|
Quote:
Lui mi ha scritto: Codice:
//meglio usare: //const string & Book::getTitle() const string Book::getTitle() { return title; } Codice:
const string & Book::getTitle() const { return title; } Inoltre perchè la referenza & prima di Book?
__________________
Vendo...nulla. Cerco...la felicità. |
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 08:59.