Dziedziczenie w C++

0

Witam,

mam pewne zadanie, które nie rozumiem do końca. Chciałbym sie Państwa dopytać o parę szczegółów:

Moje zadanie z programowania brzmi tak:

Zmodyfikuj plik dziedziczenie.cpp tak, aby:

* kompilowal się bez ostrzeżeń,
* działał poprawnie i efektywnie czyli m.in.:
      o odpowiednio inicjował klasę podstawową i składową,  //1 pkt
      o nie tworzył obiektów tymczasowych gdy nie jest to konieczne,
      o umożliwiał przesyłanie obiektów stałych/tymczasowych tam gdzie to jest możliwe/celowe. //3 pkt

dziedziczenie.cpp

// Test dziedziczenia: konstruktor, destruktor, operator przypisania.
// Pawel Pilarczyk, 22.04.2004 (wersja II).
// Modyfikacja: Tomasz Kapela, 10.04.2005

#include <cstdlib>
#include <iostream>

using std::cout;
using std::endl;

class podstawowa
{
 public:
  int liczba;

  podstawowa () : liczba(0) {  
   cout << "Konstruktor domyslny z klasy podstawowej.\n";
  }

  podstawowa (int w) : liczba(w) {  //TU
   cout << "Konstruktor specjalny z klasy podstawowej.\n";
  }

  podstawowa (podstawowa &wzor) : liczba(wzor.liczba) {
   cout << "Konstruktor kopiujacy z klasy podstawowej.\n";
  }

  podstawowa &operator= (podstawowa wzor)  {
   cout << "Operator przypisania z klasy podstawowej.\n";
   liczba = wzor. liczba;
   return *this;
  }

  ~podstawowa () {
   cout << "Destruktor z klasy podstawowej: liczba = " << liczba << ".\n";
  }
}; /* podstawowa */

class skladowa
{
 public:
  bool wartosc;

  skladowa () : wartosc(false)  {
   cout << "Konstruktor domyslny z klasy skladowej.\n";
  }

  skladowa (bool w) : wartosc(w) {
   cout << "Konstruktor specjalny z klasy skladowej.\n";
  }

  skladowa (skladowa wzor) : wartosc(wzor.wartosc) {
   cout << "Konstruktor kopiujacy z klasy skladowej.\n";
  }

  skladowa &operator= (skladowa wzor) {
   cout << "Operator przypisania z klasy skladowej.\n";
   wartosc = wzor.wartosc;
   return *this;
  }

  ~skladowa () {
    cout << "Destruktor z klasy skladowej: justowanie = " << wartosc << ".\n";
  }
}; /* skladowo */


class pochodna: public podstawowa
{
 public:
  char znak;
  skladowa justowanie;

  pochodna () : znak('!') {  
   cout << "Konstruktor domyslny z klasy pochodnej.\n";
  }

  // pomimo tej kolejnosci na liscie inicjalizacyjnej 
  // najpierw wywola sie konstruktor klasy podstawowej
  pochodna (int w, char z, bool j): znak(z) {
   cout << "Konstruktor specjalny z klasy pochodnej.\n";
  }

  pochodna (pochodna & wzor) : znak(wzor. znak) { 
   cout << "Konstruktor kopiujacy z klasy pochodnej.\n";
  }

  pochodna &operator= (pochodna wzor) {
   cout << "Operator przypisania z klasy pochodnej.\n";
   justowanie = wzor.justowanie;
   znak = wzor. znak;
   return *this;
  }

  ~pochodna () {
   cout << "Destruktor z klasy pochodnej: liczba = " << liczba 
    << ", znak = '" << znak << "', justowanie = " << justowanie.wartosc << "\n";
  }
}; /* pochodna */

// Prosze sprawdzic co sie stanie jezeli nie uzyjemy referencji przy 'p' 
std::ostream &operator << (std::ostream &str, pochodna p){
   if(p.justowanie.wartosc)
     str << p.liczba << p.znak;
   else
     str << p.znak << p.liczba;
   return str;
}

void testuj (void) {
 pochodna x (13, '%', true);
 cout << "x = " << x << endl;

 cout << "----------------------------------------------------------\n";
 {
  pochodna y (x);
  cout << "y = " << y << endl;
 }

 cout << "----------------------------------------------------------\n";
 {
  podstawowa z (x);
  cout << "z = " << z. liczba << endl;
 }
 
 cout << "----------------------------------------------------------\n";
 return;
} /* testuj */

int main (void) {
 cout << "Test dziedziczenia konstruktora, destruktora i opeartora=.\n";
 cout << "----------------------------------------------------------\n";
 testuj ();
 cout << "----------------------------------------------------------\n";
 return 0;
} /* main */

//==============================================/

Nie chodzi mi o to, by rozwiązać to zadanie, ale o to by z Państwem podzielić się paroma pytaniami, na które nie mogłem odnaleźć odpowiedzi w sieci

Otóż moje pytania:

  1. Co to za dziwna deklaracja nazwaklasy() : coś() { // definicja klasy} (jak TU)
  2. Co myślicie o punkcie 3?? Bo ja tego nie rozumiem, o co chodzi;

Z góry dzięki za odpowiedzi:D

0

ad1) Jest to po prostu przypisanie do zmiennej liczba wartości. Tak samo można przypisać w ciele konstruktora liczba = 0;

0

Ok, ale dlaczego tak sie robi?? Czy to ma jakieś znaczenie??

0

To nie jest żadne przypisanie wartości! To jest wywołanie konstruktora tego obiektu. Po co sie to stosuje?
Bo to nie jest to samo co zwykłe przypisanie wartości. Co jeśli np. pole tej klasy jest typu const? W ciele konstruktora nie da się przypisać temu polu wartości, bo ten obiekt juz istnieje. Wartość można mu przypisać tylko w chwili tworzenia!

0
alienik napisał(a)

Ok, ale dlaczego tak sie robi?? Czy to ma jakieś znaczenie??

Na liście inicjalizacyjnej możesz zainicjować składowe, będące referencjami lub const oraz możesz wywołać konstruktor klasy nadrzędnej podając mu jakieś parametry, czego nie zrobisz w ciele konstruktora. Nic innego ta lista nie daje, więc sam oceń czy ma to jakieś znaczenie czy nie.

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