Dziedziczenie konstruktor

0
#include <iostream>

using namespace std;

class Ksztalt
{
public:
    int pole;
    string nazwa;
    Ksztalt(int p, string n):pole(p),nazwa(n){}
};

class kolo : public Ksztalt
{
public:
    int promien;

public:
    void f()
    {
        cout << promien << " " << nazwa << endl;
    }
};

int main()
{
    kolo a;
    a.nazwa="kolo";
    a.promien=4;
    a.f();
    return 0;
}
 

Dlaczego ten program się nie kompiluje? Nie mogę tego rozgryźć. Coś nie tak chyba z konstruktorem jest.

3

Konstruktor domyślny ?

5

kolo dziedziczy po (inaczej mówiąc - zawiera w sobie) ksztalt. ksztalt nie ma konstruktora domyślnego. Tworząc kolo musisz utworzyć klasę-rodzica, a robisz to w sposób domyślny, czyli bez żadnych argumentów. Widzisz już problem?

0

Dzięki. A da się bez konstruktora domyślnego? Tzn. już od razu wstawić parametry

4

Następnym razem jak coś się nie kompiluje to wstaw komunikat błędu.

prog.cpp:27:10: error: use of deleted function 'kolo::kolo()'
prog.cpp:13:7: note: 'kolo::kolo()' is implicitly deleted because the default definition would be ill-formed:
prog.cpp:13:7: error: no matching function for call to 'Ksztalt::Ksztalt()'

Czytając od dołu:

  1. nie istnieje konstruktor Ksztalt(), bo zdefiniowałeś konstruktor z parametrami
  2. konstruktor bezparametrowy kolo() został usunięty, bo musiałby korzystać z bezparametrowego konstruktora klasy bazowej, którego nie ma
  3. pisząc kolo a próbujesz użyć konstruktora, który został usunięty
3

Albo zdefiniuj domyślny konstruktor dla kształtu (może być protected jeśli nie chcesz aby tylko klasy dziedziczące mogły go wywołać), albo przekazuj parametry do konstruktora rodzica w liście inicjalizacyjnej koła

3
kolo(int promien,const string &nazwa):Ksztalt(M_PI*promien*promien,nazwa),promien(promien) {}

konstruktor do klasy kolo

0
#include <iostream>

using namespace std;

class Ksztalt
{
public:
    int pole;
    string nazwa;
    Ksztalt(int p, string n):pole(p),nazwa(n){}
    Ksztalt(){}
};

class kolo : public Ksztalt
{
public:
    int promien;
    kolo():pole(3.14*promien*promien), nazwa("kolo"){}
};

int main()
{
    kolo a;
    a.nazwa="kolo";
    a.promien=4;
    a.f();
    return 0;
}
 

Kolejne pytanie. Dlaczego program się nie kompiluje? Jest blad, że klasa kolo nie ma atrybutu pole. Przeciez on powinien byc odziedziczony.

2

bezsens, używasz w konstruktorze niezainicjalizowanej składowej.

    kolo(int promien):Ksztalt(M_PI*promien*promien,"kolo"),promien(promien) {}
2

Nie możesz ustawiać pola klasy wyżej bezpośrednio¹ w liście inicjalizacyjnej konstruktora klasy dziedziczącej. Wywołaj tak jak @_13th_Dragon polecił - konstruktor kształtu.

¹ możesz przy dziedziczeniu wirtualnym, jeśli klasę dziedziczoną wirtualnie uznasz za pole.

3

Jeśli to program na ocenę, to masz w nim kilka błędów stylistycznych:

  • klasy w obecnym kształcie to struktury, czyli użyj struct zamiast class (pola publiczne)
  • jeśli nazwy klas mają być z dużej to niech będą z dużej wszędzie
  • parametry konstruktora o mało czytelnych nazwach p i n kwalifikują program (i twórcę) do odstrzału (czyt. negatywna ocena)
  • to samo jeśli chodzi o funkcję f()
0
 #include <iostream>

using namespace std;

class Ksztalt
{
public:
    int pole;
    string nazwa;
    Ksztalt(int p, string n):pole(p),nazwa(n){}
    virtual void Wyswietl();
};

void Ksztalt::Wyswietl()
{
    cout << pole << endl;
}

class kolo : public Ksztalt
{
public:
    int promien;
    kolo(int p,const string &nazwa):Ksztalt(promien*2*3.14,nazwa),promien(p){}
    void Wyswietl();
};

void kolo::Wyswietl()
{
    cout << pole << endl;
}

int main()
{
    Ksztalt *p;
    kolo b(7,"kolko");
    p=&b;
    p->Wyswietl();
    return 0;
}

Dobra. Następne pytanie. Dlaczego mi teraz wyskakują w programie jakieś śmieci z pamięci? Przecież atrybut pole powinien być zainicjowany.

2

Bo zmieniłeś kod od @_13th_Dragon bez jego zrozumienia. promien nie jest zainicjalizowane w momencie wywoływania kontruktora Ksztalt

0

Kurde. Chyba czaje. Najpierw jest wywolywany konstruktor klasy bazowej. On potrzebuje 2 parametrow, to bierze je od listy inicjacyjnej konstruktora klasy pochodnej. Dopiero potem jest uruchamiany konstruktor klasy pochodnej.

1
Mikilll napisał(a):

inicjacyjnej

inicjalizacyjnej
Inicjacja może być przy seksie.

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