POO en C++. Exemple Author-Book. Un objecte té com a data membre un altre objecte
Contingut
Introducció
El punt de partida són els exemples i teoria que aquí es mostra:
La pregunta a stackoverflow:
Defineixo la calsse Author amb el mètode setEmail(). Defineixo la classe Book, amb Author com a data member. El problema és que des del Book vull canviar el nom de l'autor:
cppbook.getAuthor().setEmail("peter@gmail.com");
i això no em sortia. La solució és que el mètode getAuthor() l'he de passar per referència. No n'hi ha prou amb què Author també estigui per referència. A més, com es comenta en el primer enllaç, s'ha de fer servir sempre que es pugui passar per referència i const per tal d'eliminar la creació d'objectes clon, i així millorar la performance.
Desenvolupament
En l'enllaç hi ha tot el codi generats.
- valors passats per value: no funciona setEmail()
- valors passats per value: funciona setEmail()
- valors passats per referència: funciona setEmail()
- valors passats per referència i const: funciona setEmail()
- Fitxer:Author book c++.zip
La idea és que
void Book::setAuthorMail(string mail) { //ara ja no cal author.setEmail(mail); }
funciona sempre perquè amb aquesta funció modifico des de Book, directament el mail de l'autor. Però perdo encapsulament perquè no té res a veure Book amb Author, i no té cap sentit que des de Book faci referència la mail de l'autor.
Per tant, el que he de fer és que des de Book pugui fer referència a l'autor:
Author & Book::getAuthor() { return author; }
però amb referència (&), i així ja puc fer servir:
cppbook.getAuthor().setEmail("peter@gmail.com");
perquè si no poso la referència es crea una còpia de l'objecte, i quan faig setEmail no s'entera el meu objecte.
Es mostra el codi de valors passats per referència i const
Author.h
/* Header for the Author class (Author.h) */ #ifndef AUTHOR_H #define AUTHOR_H #include <string> using namespace std; class Author { private: string name; string email; public: Author(const string & name, const string & email); string getName() const; string getEmail() const; void setEmail(const string email); void print() const; }; #endif
Author.cpp
// g++ -c Author.cpp #include <iostream> #include "Author.h" using namespace std; Author::Author(const string & name, const string & email) { this->name = name; this->email = email; } string Author::getName() const { return name; } string Author::getEmail() const { return email; } void Author::setEmail(const string email) { this->email = email; } // print in the format "name (gender) at email" void Author::print() const { cout << name << "-" << email << endl; }
Book.h
#ifndef BOOK_H #define BOOK_H #include <string> #include "Author.h" // Use the Author class using namespace std; class Book { private: string name; Author author; // data member author is an instance of class Author public: Book(const string & name, const Author & author); string getName() const; Author & getAuthor(); // Returns an instance of the class Author. Necessari que sigui per referència per tal de què // retorni l'autor que està emmagatzemat a la classe. void print() const; void setAuthorMail(string mail); }; #endif
Book.cpp
/* Implementation for the class Book (Book.cpp) */ #include <iostream> #include "Book.h" using namespace std; Book::Book(const string & name, const Author & author) : name(name), author(author) { } string Book::getName() const { return name; } Author & Book::getAuthor() { //no pot ser const perquè pretenc canviar-lo return author; } // print in the format ""Book-name" by author-name (gender) at email" void Book::print() const { cout << name << " - " << author.getEmail() << endl; } void Book::setAuthorMail(string mail) { author.setEmail(mail); }
TestBook.cpp
// g++ -o TestBook TestBook.cpp Book.cpp Author.cpp #include <iostream> #include "Book.h" using namespace std; int main() { //string nom = "John"; //no cal perquè no pretenc canviar-lo //string mail = "john@gmail.com"; //no cal perquè no pretenc canviar-lo Author john("John","john@gmail.com"); john.print(); // John-john@gmail.com Book cppbook("C++ Introduction", john); cppbook.print(); cppbook.getAuthor().setEmail("peter@gmail.com"); cppbook.print(); //C++ Introduction - peter@gmail.com cppbook.setAuthorMail("andrew@gmail.com"); cppbook.print(); //C++ Introduction - andrew@gmail.com }
creat per Joan Quintana Compte, juny 2016