Skocz do zawartości

Pytanie teorytyczne- obiektowość.


kt1117

Rekomendowane odpowiedzi

Ostatnio uczę się obiektowości w C++ i napisałem program, który losuje liczby nie powtarzając się w obiektowości. I napotkałem dziwną sytuację. Zrobiłem konstruktor, tam wyzerowałem wszystkie zmienne, wypytałem się użytkownika o liczby i wywołałem inną metodę. W tej metodzie odwołałem się zmiennych, które przypisałem w konstruktorze, pytając się usera o liczby. I tu patrzę, a metoda wywala mi wartości z kosmosu, znaczy nie wyzerowana. I tu moje pytanie, jaki zakres ma zmienna w klasie?

Odnośnik do komentarza
Udostępnij na innych stronach

podaj kod

Odnośnik do komentarza
Udostępnij na innych stronach

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

class losowanie
{
    int wylosowane[8];
    int podane[10];
    int a;
    int b;
public:
    void wylosowywanie();
    losowanie();
    ~losowanie();
};

losowanie::losowanie()
{
    srand(time(0));
    a=0;
    b=0;

    losowanie::wylosowywanie();

};

void losowanie::wylosowywanie()
{
    cout<<"Podaj 10 liczb: "<<endl;
    cin>>podane[0]>>podane[1]>>podane[2]>>podane[3]>>podane[4]>>podane[5]>>podane[6]>>podane[7]>>podane[8]>>podane[9];
    do
    {
        do
        {


            a=((rand())%11)-1;
            a=losowanie::podane[a];

        }
        while (a==wylosowane[0] or a==wylosowane[1] or a==wylosowane[2] or a==wylosowane[3] or a==wylosowane[4] or a==wylosowane[5] or a==wylosowane[6] or a==wylosowane[7]);

        wylosowane[b]=a;
        b++;


    }
    while (b<10);

};



losowanie::~losowanie()
{
    cout<<"Liczby to:"<<wylosowane[0]<<", "<<wylosowane[1]<<", "<<wylosowane[2]<<", "<<wylosowane[3]<<", "<<wylosowane[4]<<", "<<wylosowane[5]<<", "<<wylosowane[6]<<", "<<wylosowane[7]<<"."<<endl;
};

int main()
{
    losowanie::losowanie();
    return 0;
}

Ten kod działa, zaraz dam ten poprzedni, tylko muszę go odtworzyć.

E:

Ten dziwny:

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

class losowanie
{
    int wylosowane[8];
    int podane[10];
    int a;
    int b;
public:
    void wylosowywanie();
    losowanie();
    ~losowanie();
};

losowanie::losowanie()
{
    srand(time(0));
    a=0;
    b=0;
    int wylosowane[8]={0,0,0,0,0,0,0,0};
    int podane[10]={0,0,0,0,0,0,0,0,0,0};
    cout<<"Podaj 10 liczb: ";
    cin>>podane[0]>>podane[1]>>podane[2]>>podane[3]>>podane[4]>>podane[5]>>podane[6]>>podane[7]>>podane[8]>>podane[9];

    losowanie::wylosowywanie();

};

void losowanie::wylosowywanie()
{

    do
    {
        do
        {


            a=((rand())%11)-1;
            a=losowanie::podane[a];

        }
        while (a==wylosowane[0] or a==wylosowane[1] or a==wylosowane[2] or a==wylosowane[3] or a==wylosowane[4] or a==wylosowane[5] or a==wylosowane[6] or a==wylosowane[7]);

        wylosowane[b]=a;
        b++;


    }
    while (b<10);

};



losowanie::~losowanie()
{
    cout<<"Liczby to:"<<wylosowane[0]<<", "<<wylosowane[1]<<", "<<wylosowane[2]<<", "<<wylosowane[3]<<", "<<wylosowane[4]<<", "<<wylosowane[5]<<", "<<wylosowane[6]<<", "<<wylosowane[7]<<"."<<endl;
};

int main()
{
    losowanie * obiekt=new losowanie;
    delete obiekt;
    return 0;
}

I ten, który według mnie powinien działać a wywala błąd:

w\losowanie\main.cpp||In constructor 'losowanie::losowanie()':|
w\losowanie\main.cpp|24|warning: extended initializer lists only available with -std=c++0x or -std=gnu++0x|
w\losowanie\main.cpp|24|error: cannot convert '<brace-enclosed initializer list>' to 'int' in assignment|
w\losowanie\main.cpp|25|warning: extended initializer lists only available with -std=c++0x or -std=gnu++0x|
w\losowanie\main.cpp|25|error: cannot convert '<brace-enclosed initializer list>' to 'int' in assignment|
||=== Build finished: 2 errors, 2 warnings ===|

,

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

class losowanie
{
    int wylosowane[8];
    int podane[10];
    int a;
    int b;
public:
    void wylosowywanie();
    losowanie();
    ~losowanie();
};

losowanie::losowanie()
{
    srand(time(0));
    a=0;
    b=0;
    wylosowane[8]={0,0,0,0,0,0,0,0};
    podane[10]={0,0,0,0,0,0,0,0,0,0};
    cout<<"Podaj 10 liczb: ";
    cin>>podane[0]>>podane[1]>>podane[2]>>podane[3]>>podane[4]>>podane[5]>>podane[6]>>podane[7]>>podane[8]>>podane[9];

    losowanie::wylosowywanie();

};

void losowanie::wylosowywanie()
{

    do
    {
        do
        {


            a=((rand())%11)-1;
            a=losowanie::podane[a];

        }
        while (a==wylosowane[0] or a==wylosowane[1] or a==wylosowane[2] or a==wylosowane[3] or a==wylosowane[4] or a==wylosowane[5] or a==wylosowane[6] or a==wylosowane[7]);

        wylosowane[b]=a;
        b++;


    }
    while (b<10);

};



losowanie::~losowanie()
{
    cout<<"Liczby to:"<<wylosowane[0]<<", "<<wylosowane[1]<<", "<<wylosowane[2]<<", "<<wylosowane[3]<<", "<<wylosowane[4]<<", "<<wylosowane[5]<<", "<<wylosowane[6]<<", "<<wylosowane[7]<<"."<<endl;
};

int main()
{
    losowanie * obiekt=new losowanie;
    delete obiekt;
    return 0;
}

Odnośnik do komentarza
Udostępnij na innych stronach

nie wywołuje sie konstruktora ot tak, musisz stworzyć obiekt, a potem go skasować:

losowanie* los = new losowanie();
delete los;

Odnośnik do komentarza
Udostępnij na innych stronach

To mnie w kursie okłamali, ale dalej konstruktor nie zmienia/ zmienia zbyt późno wartość wymienionych zmiennych, i dlaczego muszę jeszcze raz deklarować zmienne, które zadeklarowałem w definicji klasy?

E:

Teraz mam w miarę logiczny (wg. mnie) i działa:

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

class losowanie
{
    int wylosowane[8];
    int podane[10];
    int a;
    int b;
public:
    void wylosowywanie();
    losowanie();
    ~losowanie();
};

losowanie::losowanie()
{
    srand(time(0));
    a=0;
    b=0;

    cout<<"Podaj 10 liczb: "<<endl;
    cin>>podane[0]>>podane[1]>>podane[2]>>podane[3]>>podane[4]>>podane[5]>>podane[6]>>podane[7]>>podane[8]>>podane[9];
    losowanie::wylosowywanie();

};

void losowanie::wylosowywanie()
{

    do
    {
        do
        {


            a=((rand())%11)-1;
            a=losowanie::podane[a];

        }
        while (a==wylosowane[0] or a==wylosowane[1] or a==wylosowane[2] or a==wylosowane[3] or a==wylosowane[4] or a==wylosowane[5] or a==wylosowane[6] or a==wylosowane[7]);

        wylosowane[b]=a;
        b++;


    }
    while (b<10);

};



losowanie::~losowanie()
{
    cout<<"Liczby to:"<<wylosowane[0]<<", "<<wylosowane[1]<<", "<<wylosowane[2]<<", "<<wylosowane[3]<<", "<<wylosowane[4]<<", "<<wylosowane[5]<<", "<<wylosowane[6]<<", "<<wylosowane[7]<<"."<<endl;
};

int main()
{
    losowanie*los=new losowanie();
    delete los;
    return 0;
}

Tylko nie wiem jak wyzerować tablice, bo widocznie zapis array[n]={a,b,c,......,m} działa tylko przy deklaracji, a nie można nadać wartości zmiennej w deklaracji klasy, tzn. że muszę zerować każdą komórkę osobno?

Odnośnik do komentarza
Udostępnij na innych stronach

skoro chce, by zmienne miały zasięg obiektu, to przecież musi on istnieć. sam głupoty gadasz.

Odnośnik do komentarza
Udostępnij na innych stronach

Listę inicjalizacji można użyć tylko w czasie tworzenia obiektu (deklaracja)

Wiesz co to jest deklaracja? ;)

 

 

Czyli nie trzeba pisać losowanie: :( ...), nawet poza blokami funkcji zadeklarowanych w obiektach?

W metodach danej klasy przy odwoływaniu się do funkcji, która także jest metodą(tej samej klasy) nie musisz się bawić w takie pierdoły. Do dyspozycji jest wskaźnik this, który załatwia takie sprawy.

 

Przy samym konstruktorze inicjuj składniki klasy:

 

class Test

{

 

Test():k(0)

{

 

}

 

private:

int k;

};

 

Jest to znacznie szybsze.

Listę inicjalizacji można użyć tylko w czasie tworzenia obiektu

Można użyć tylko dla typów wbudowanych i pod'ów a nie obiektów.

 

nie wywołuje sie konstruktora ot tak, musisz stworzyć obiekt, a potem go skasować:

Przecież tworzy obiekt?

Odnośnik do komentarza
Udostępnij na innych stronach

Chodziło mi o wydajność między:

 

 

class T

{

T():k(costam){}

private:

int k;

};

 

 

a

 

 

class T

{

T(){k=costam;}

private:

int k;

};

 

 

Chociaż w przypadku klas i tak rób osobno deklaracje/definicje. Klasa -> plik deklaracje Klasa.h + definicje Klasa.cpp

Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...