Przeładowanie funkcji składowych - błąd

0

Witam, mam taki kod:

#include <iostream>
using namespace std;

class exp
{
       const double stala;
       string x;
      char a, b;

    public:

    exp(double wsk_a, string pp):stala(wsk_a)
    {
        x = pp;

        cout << "Twoj tekst to: " << pp << endl << endl;
        cout << "Twoja liczba to: " << wsk_a << endl;
    }

    exp(char c, char g)
    {
        a = c;
        b = g;
    }

};



int main()
{

cout << "podaj liczbe: ";
double liczba;
cin >> liczba;
cout << "Wpisz tekst: ";
string tekst;
cin >> tekst;
exp(liczba,tekst);


}
 

Według definicji przeładowania funkcje muszą się różnić typem lub ilością argumentów. I jest tak w moim przypadku. To dlaczego do jasnej cholery ciagle mi wywala błąd:

error: uninitialized member exp 'exp::stala' with 'const' type 'const double'

Rozwiązanie jest zapewne proste a ja tego nie widzę... może mi to ktoś wyjaśnic?

0

W drugim konstruktorze nie inicjalizujesz stałej.

0

Przecież nie korzystam tam ze stałej to po co?

To działa, ale nie rozumiem dlaczego tak jest....

0

po to żeby się błąd nie pojawiał

0

No toś mi naprawdę pomógł -.-
Może mi wyjaśnisz dlaczego tak jest, że ten błąd się pojawia przy przeładowaniu co?
Twoje wytłumaczenie mi tego jest tak samo suche jak kurs Objective-C w dokumentacji Apple -.-

0

Stały element klasy tylko podczas konstruowania obiektu może otrzymać jakąś wartość, której potem nie można zmienić. Dlatego też jest obowiązek zainicjalizowania stałej. Jeśli tego nie zrobisz w konstruktorze, to gdzie?

0

Zrobiłem to przecież w pierwszym konstruktorze?

0

Ale te konstruktory z siebie nie korzystają więc co to ma do rzeczy?

0

Chodzi o to, że chcę tylko w tym pierwszym konstruktorze skorzystać ze składnika const. Więc po co mam potem w jego przeładowanej wersji również umieszczać ten składnik na liście inicjalizacyjnej ?

0

Ponieważ dwa konstruktory są całkowicie niezależne od siebie, i są dwoma różnymi sposobami otrzymania obiektu jaki określasz.
Nie ma czegoś takiego jak składnik tylko dla jednego konstruktora. Składnik jest elementem klasy, a konstruktory tworzysz po to, by obiekt takiej klasy utworzyć.

0

No..powiedzmy, że czaje ;)

0

No dobra ale jak utworze sobie takie coś:

 #include <iostream>
using namespace std;

class sprzeg
{

  float f;
  double d;

  public:
  sprzeg()
  {
     cout << "Pracuje ja, konstruktor!";
  }
  //sprzeg(double dll, float fll, int srara);
};

int main()
{

}

To już błędów nie wywala... wystarczy, że jakiś const dam i już sie sypie..nie czaje tego

0

Czyli innymi słowy konstruktor klasy, musi jakby pracować na wszystkich zadeklarowanych przeze mnie zmiennych i stałych tak?

0

Każda stała składowa klasy musi być inicjalizowana poprzez konstruktor w liście inicjalizacyjnej.
Jeśli nie widzisz w tym wymogu sensu, to najprawdopodobniej albo nie powinieneś określać składowej jako stała, albo po prostu jej nie potrzebujesz.

Tego wymogu co do zmiennych nie ma, z racji że potem i tak je możesz zmienić. Jeśli natomiast dałoby się pominąć stałą, to zostałyby w niej śmieci, ktorych nie mógłbyś zmienić. A w takim wypadku stała składowa która tylko trzyma śmieci zdecydowanie nie ma sensu.

0

No tak..racja przecież nie możemy napisać

private:
const int stala = 14;

dlatego musi być tam gdzie musi :D :) juz czaje, dziekuje!

0
Jefrey napisał(a)

Chodzi o to, że chcę tylko w tym pierwszym konstruktorze skorzystać ze składnika const. Więc po co mam potem w jego przeładowanej wersji również umieszczać ten składnik na liście inicjalizacyjnej ?

Jeśli chcesz korzystać ze stałej tylko i wyłącznie w tym jednym konstruktorze, to niech ona nie będzie składnikiem klasy tylko zwykła stałą:

class exp
{
    exp(double wsk_a, string pp)
    {
       const double stala = wsk_a;
       // ...
    }
};

Natomiast jeśli chcesz mieć możliwość korzystania ze stałej również w innych miejscach i na prawdę musi ona być składnikiem klasy, to musisz zagwarantować, że będzie ona zawsze zainicjowana, nie ważne jakiego konstruktora użyjemy, stała musi ZAWSZE być zainicjowana. Nie może być tak, że jeden konstruktor zainicjuje stałą a inny nie.

Eksperymentalnie załóżmy, że nie każdy konstruktor musi inicjować stałą:

clas exp {
   const double stala;
   exp() {} // nie inicjuje
   exp(double x) : stala(x) {} // inicjuje
}

Jeśli użyć by konstruktora, który jej nie inicjuje:

exp obiekt();

wtedy możliwe byłoby odwołanie się do niezainicjowanej stałej:

cout << obiekt.stala;

W C++ stała nie może być niezainicjowana. Było by to nielogiczne ze względu na to, że stałej wartości nie można zmienić. Raz niezainicjowana stała pozostałby niezainicjowana na zawsze - byłaby bezużyteczna.

0

Już rozumiem ;)
i to dlatego kompilator do tego nie dopuszcza

0
 class exp
{
    exp(double wsk_a, string pp):stala(wsk_a)
    {
       const double stala = wsk_a;
       // ...
    }
};

Jednak ten przykład się nie kompiluje

0

Zalecam czytać komunikaty kompilatora...
error: class 'exp' does not have any field named 'stala'

Stała lokalna w konstruktorze nie ma nic wspólnego ze składowymi w klasie.

0

W twojej poprzedniej wypowiedzi umiesciles ja na liscie twierdzac, ze dziala.. ale nie dziala wiec? Dlatego pytam ;)

0
Jefrey napisał(a)
 class exp
{
    exp(double wsk_a, string pp):stala(wsk_a)
    {
       const double stala = wsk_a;
       // ...
    }
};

Jednak ten przykład się nie kompiluje

Ponieważ w tej klasie w ogóle nie posiadasz składowej "stala". A na liście inicjalizacyjnej próbujesz zainicjalizować coś o czym nie ma mowy w klasie.
Serio... komunikat kompilatora jest czytelny. A jeśli w klasie masz coś więcej (czego nie zapostowałeś) i twierdzisz że powód błędu jest inny to bądź taki miły i wklej ten bląd :)

0
Jefrey napisał(a)

Jednak ten przykład się nie kompiluje

Zemsta Kopiego-Paste'a.
Poprawiłem.
Zresztą ten przykład jest trochę bez sensu. Nie skupiaj się na nim ;) Chodziło o zaprezentowanie nieużywania stałej jako składnika klasy.

0

Ok juz wszystko czaje ;)
Dzieki wielkie, pozdrawiam

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