kompozycja w c++

0

Cześć,

uczę się programować w c++ i w jednym z poradników znalazłem przykład prostej kompozycji na której chciałem trochę potrenować.
Program staram się uruchomić w QT Creatorze jednak dostaje błędy z którymi nie mogę sobie poradzić. Podpowie ktoś co robię nie tak?

ksiazka.h

#ifndef KSIAZKA_H
#define KSIAZKA_H

#include "Osoba.h"

class Ksiazka
{
public:
    Ksiazka(Osoba autor, QString tytul, int cena);
    Osoba podajAutor();
    QString podajTytul();
    int podajCena();

private:
    Osoba autor;
    QString tytul;
    int cena;
};

#endif // KSIAZKA_H

ksiazka.cpp

#include "Ksiazka.h"

#include <Osoba.h>
#include <QString>

Ksiazka::Ksiazka(Osoba autor, QString tytul, int cena)
{
    autor = autor;
    tytul = tytul;
    cena = cena;
}
Osoba Ksiazka::podajAutor()
{
    return autor;
}
QString Ksiazka::podajTytul()
{
    return tytul;
}
int Ksiazka::podajCena()
{
    return cena;
}

osoba.h

#ifndef OSOBA_H
#define OSOBA_H

#include <QString>

class Osoba
{
public:
    Osoba(QString nazwisko, QString imie);
    QString podajNazwisko();
    QString podajImie();

private:
     QString nazwisko;
     QString imie;

};

#endif // OSOBA_H

osoba.cpp

#include "Osoba.h"

#include <QString>

Osoba::Osoba(QString nazwisko, QString imie)
{
    nazwisko = nazwisko;
    imie = imie;
}

QString Osoba::podajNazwisko()
{
return nazwisko;
}

QString Osoba::podajImie()
{
    return imie;
}

dostaje taki błąd:
błąd: no matching function for call to 'Osoba::Osoba()' Ksiazka::Ksiazka(Osoba autor, QString tytul, int cena)
w lini:
Ksiazka::Ksiazka(Osoba autor, QString tytul, int cena)

jeśli klasa osoba nie przyjmuje w konstruktorze żadnych parametrów program startuje

4

Nie masz listy inicjalizacyjnej konstruktora, więc wszystkie elementy klasy Ksiazka - w tym autor są tworzone za pomocą ich konstruktora domyślnego¹, którego autor - Osoba nie ma. Użyj listy inicjalizacyjnej konstruktora, zamiast tworzyć potworki typu a=a

¹ (ok, są default-initialized, ale to nie ten poziom)

0

udało się rozwiązać jeden problem i pojawił się kolejny, dodałem

Osoba::Osoba(QString nazwisko, QString imie)
{
    nazwisko = nazwisko;
    imie = imie;
}
Osoba::Osoba()
{

}

i program kompiluje się, jednak kiedy próbuje utworzyć obiekt w main:

Ksiazka k = new Ksiazka(new Osoba("imie","nazwisko"),"tytul",33);

dostaje:
błąd: no matching function for call to 'Ksiazka::Ksiazka(Osoba*, const char [7], int)'

                                                           ^
1

Dlaczego wszędzie używasz new? To nie java, jak chcesz utworzyć obiekt to napisz to normalnie, QString("foo"), a nie new QString("foo"). Wskaźnik na typ i typ to różne rzeczy.

Tak przy okazji: staraj się nie używać nagiego new (a już na pewno delete) - to antyidiom w C++. Masz mądre wskaźniki, masz kontenery.

0

Uczę się kopiując przykłady z internetu.
Usunięcie new faktycznie pomogło, chyba muszę nadrobić trochę teorii z c++...

0

ok będę zwracał uwagę na datę przykładów.

Mam jeszcze jedno ostatnie pytanie.
Dodałem 2 nowe metody do klasy osoba

QString Osoba::zapiszNazwisko(QString nazwisko)
{
    this->nazwisko = nazwisko;
}
QString Osoba::zapiszImie(QString imie)
{
    this->imie = imie;
}

Obiekt ksiazka tworzę w ten sposób

Ksiazka k =  Ksiazka(Osoba("nazwisko","imie"),"tytul",323);

Czy w tak utworzonym obiekcie można zmienić w prosty sposób imię i nazwisko obiektu Osoba?

próbowałem coś takiego:

k.podajAutor().zapiszImie("Nowe imie");

ale dostaje błąd: Program nieoczekiwanie przerwał pracę.

Mógłbym dodać kolejną metodę w klasie Ksiazka:

void Ksiazka::setAutor(Osoba autor)
{
    this->autor = autor;
}

a potem w main zrobić coś takiego:

Osoba nowa("nowe nazwisko", "nowe imie");
k.setAutor(nowa);

ale czy to jest poprawny zapis?
może da się to zrobić bez tworzenie nowego obiektu?

1

Poczytaj o wskaźnikach i referencjach. Twoja metoda podajAutor tworzy kopię autora.

0

czytałem i nawet próbowałem ich używać ale to chyba jeszcze nie mój level.
Sama zmiana metody podajAutor aby zwracała wskaźnik nie wystarczy?
Program się kompiluje ale

k.podajAutor().zapiszImie("Nowe imie");

nic nie zmienia

Osoba Ksiazka::podajAutor()
{
    Osoba *d = &autor;
    return *d;
}
0

Cały czas zwracasz kopię. Zwróć referencję.

Osoba& Ksiazka::podajAutor()
{
	return autor;
}
0

ok teraz już czaje, działa, dzięki za pomoc :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1