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