• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Korelacja miedzy klasami a ich atrybutami. C++

Object Storage Arubacloud
0 głosów
614 wizyt
pytanie zadane 5 września 2015 w C i C++ przez 0xf Dyskutant (8,180 p.)

Witam, mam problem zeby go wyjasnic podam przykladowy kod ktory odpowiada zazadanej przezmnie operacji :

#include <iostream>

using namespace std;

class Klasa1
{
int a;
float b;

public:
void wczytaj()
{
cin>>a>>b;
}

};

class Klasa2
{
int c=Klasa1::a * Klasa1::b;

public:
void wyswietl()
{
cout<<c;
}


};

int main()
{
Klasa1 a1;
Klasa2 a2;
a1.wczytaj();
a2.wyswietl();

return 0;
}

Blad :

error: incomplete type 'Klasa1' used in nested name specifer

 

Z gory dzieki za pomoc, pozdrawiam

4 odpowiedzi

+1 głos
odpowiedź 5 września 2015 przez niezalogowany

Słuchaj, zupełnie nie wiem jak to zrobić, ale wytłumaczę ci, dlaczego to nie działa:

W klasie Klasa2 chcesz, żeby zmienna c była zainicjalizowana dwoma zmiennymi pomnożonymi przez siebie z klasy Klasa1. Nie da się tak, bo:

  1. Nie można inicjalizować zmiennej w taki sposób, można ją inicjalizować albo w konstruktorze, albo w jakiejś funkcji składowej. Nie możesz tak o do niej dopisać jej wartość podczas deklarowania jej. Po prostu tak nie można.
  2. Nawet jeśli zainicjalizujesz tą zmienną w np. konstruktorze, to zmienne z klasy Klasa1 są prywatne. Więc musisz je włożyć do zakresu public. I co, problem rozwiązany? Nie, bo tamte zmienne z klasy Klasa1 nie mają żadnych początkowych wartości. Więc nie możesz ich użyć, skoro nic w nich nie ma O_o Możesz je zrobić static, ale i tak coś mi nie działa :/

Poczekaj może jeszcze troche, to z tym pokombinuję...

komentarz 5 września 2015 przez Sebastian Fojcik Nałogowiec (43,020 p.)
"Zupełnie nie wiem jak to zrobić"

Aj tam nie wiesz. Wszystko pięknie opisałeś i stwierdzam, że to prawie zadziała. Ale składniki w Klasa1 MUSZĄ być statyczne, bo inaczej nie będzie wiadomo z którego obiektu mają być wyciągnięte.

Wierzę w Twoje zdolności i chęci! Napisz ten kod! DO IT!

Jak nie dasz rady, to ja to napiszę, ale spróbuj się jednak nie poddać. Filip! Filip! Filip! :-D
komentarz 5 września 2015 przez niezalogowany

Dobra, jedyne co wymyśliłem, to jeden z najprostszych sposobów, bo to co ty zrobiłeś, było tak pokręcone, że nie wiem jakby to inaczej zrobić ;) Tutaj masz kod, który powinieneś od razu zrozumieć, bo i tak jest strasznie prosty:

#include <iostream>

using namespace std;

class Klasa1
{
public:
    int a;
    float b;

    void wczytaj()
    {
        cin >> a >> b;
    }
};

class Klasa2
{
    int c;

public:

    void wczytaj(int a,float b)
    {
        c=a*b;
    }

    void wyswietl()
    {
        cout << c;
    }
};

int main()
{
    Klasa1 a1;
    Klasa2 a2;
    a1.wczytaj();
    a2.wczytaj(a1.a,a1.b);
    a2.wyswietl();

    return 0;
}

Najpierw porządnie się naucz C++ (szczególnie obiektowości), a potem sobie zrób jakiś porządny, obiektowy program ;)

komentarz 5 września 2015 przez niezalogowany
@Sebastian Fojcik - dzięki bardzo za wiarę :D

Tylko, że właśnie zrobiłem te składniki jako statyczne, tylko że wtedy wyskakuje mi error, bo o ile pamiętam, statyczny składnik klasy można inicjalizować tylko poza klasą :|
komentarz 5 września 2015 przez Sebastian Fojcik Nałogowiec (43,020 p.)

Miałem na myśli coś w tym stylu :-)
Inicjalizacja poza klasą w niczym nie przeszkadza. Ważne tylko, aby NAJPIERW wywołać Klasa1::wczytaj() a dopiero PÓŹNIEJ utworzyć obiekt Klasa2, bo jest on inicjalizowany za pomocą a i b. Mimo wszystko, jest to katastrofalne rozwiązanie :P

#include <iostream>

using namespace std;

class Klasa2; // Deklaracja klasy, aby 'firend' działało

class Klasa1
{
public:
	static int a;
	static float b;

	void wczytaj()
	{
		cin >> a >> b;
	}
	friend Klasa2;
};

int Klasa1::a = 0;
float Klasa1::b = 0;

class Klasa2
{
	int c;

public:

	// Konstruktor inicjalizujący 'c' iloczynem 'a' i 'b'
	Klasa2()
		:c( Klasa1::a * Klasa1::b ) {}

	void wyswietl()
	{
		cout << c;
	}
};

int main()
{
	Klasa1 a1; // Tworzymy obiekt z Klasa1
	a1.wczytaj(); // Wczytujemy a i b
	Klasa2 a2; // Tworzymy obiekt z Klasa2 i zmienną c inicjalizujemy iloczynem a i b
	a2.wyswietl(); // Wyświetlamy iloczyn

	return 0;
}

Ale Twój program też jest okej :D

komentarz 5 września 2015 przez 0xf Dyskutant (8,180 p.)
Panowie dzieki, zaraz to zaaplikuje do swojego kodu tylko musze to przemyslec bo te pare linijek moze mi rozsypac 200 linii :(
komentarz 5 września 2015 przez niezalogowany

Ooo, super! I to jest gotowy program! Tylko zastanawiałem się, dlaczego mi właśnie friend class Klasa2 nie działa, a trzeba było zadeklarować klasę nad pierwszą klasą. Good job yes ;) Mój kod (którego tutaj nie wkleiłem) wyglądał... No, tak samo, tylko że te statyczne składniki były private, bo i tak była przyjaźń z tamtą klasą, więc nie musiały być publiczne. No i ta deklaracja na górze ;) Weź zamień ten komentarz w odpowiedź, to ci łapkę w górę dam :D

komentarz 5 września 2015 przez Sebastian Fojcik Nałogowiec (43,020 p.)
edycja 5 września 2015 przez Sebastian Fojcik
Składniki statyczne są public, bo skopiowałem twój kod i przerobiłem Hehe XDD
Dzięki wielkie :P

Ja bym jeszcze ulepszył ten kod i zrobił dodatkową metodę dla Klasa2 wczytującą zmienne a i b. Ale mimo wszystko, nadal musisz NAJPIERW wywołać Klasa1::wczytaj(), a potem dopiero Klasa2::wczytaj().

Jeżeli nie rozumiesz dlaczego ta kolejność jest taka ważna, to napisz. Wytłumaczę później nieco lepiej. Albo Filip :-) On też na pewno rozumie dlaczego. :D
komentarz 5 września 2015 przez niezalogowany
Mój kod ma prawa autorskie, więc lepiej uważaj! :D

Kolejność czego? Deklarowania klas? Chodzi ci o zadeklarowanie klasy Klasa 2 nad definicją klasy Klasa1? Jeśli o to ci chodzi, to wiem, bo jakby tego nie było, to klasa Klasa1 by nie wiedziała czym jest Klasa2 i niemogłaby się z nią zaprzyjaźnić :)
0 głosów
odpowiedź 5 września 2015 przez Szahid Pasjonat (20,930 p.)
Spróbuj dać public: na samej górze ( nad adryputami w klasie)
komentarz 5 września 2015 przez Szahid Pasjonat (20,930 p.)
PS Widze że odrabia się prace domowe :)
komentarz 5 września 2015 przez 0xf Dyskutant (8,180 p.)
nie dziala, nie odrabia sie pracy domowej :D
0 głosów
odpowiedź 5 września 2015 przez Tomasz90 Nałogowiec (25,140 p.)
w Klasa2 gdy tworzysz zmienną c odwołujesz się do prywatnych pól. Musiałbyć napisać sobie gettery w Klasa1 które zwrócą Ci te pola.
komentarz 5 września 2015 przez 0xf Dyskutant (8,180 p.)
jak sie deklaruje gettery ?
komentarz 5 września 2015 przez Tomasz90 Nałogowiec (25,140 p.)
int getA() {
   return a;
}

float getB() {
   return b;
}

obie te metody dodajesz do Klasa1 i mają być publiczne. Potem zamieniasz w Klasa2

int c=Klasa1::getA() * Klasa1::getB();

 

No ale ogólnie dziwnie to masz zrobione bo c++ chyba nie przypisuje wartości domyślnych dla pól w klasie. Lepiej jakbyś w kontruktorze to inicjalizował wszystko. Tzn

w Klasa2 tworzysz pole Klasa1 obj i pole int c;

Piszesz konstruktor w Klasa2 który ma 2 parametry: obiekt Klasa1 i jakąś liczbę całkowitą. Za jego pomocą inicjalizujesz sobie te pola w Klasa2.

 

 

0 głosów
odpowiedź 5 września 2015 przez Sebastian Fojcik Nałogowiec (43,020 p.)
// Przerobiony kod Filipa ze zmiennymi statycznymi :-)
#include <iostream>

using namespace std;

class Klasa2; // Deklaracja klasy, aby 'firend' działało

class Klasa1
{
	static int a;
	static float b;

public:
	void wczytaj()
	{
		cin >> a >> b;
	}
	friend Klasa2;
};

int Klasa1::a = 0;
float Klasa1::b = 0;

class Klasa2
{
	int c;

public:

	// Konstruktor inicjalizujący 'c' iloczynem 'a' i 'b'
	void wczytaj()
	{
		c = Klasa1::a * Klasa1::b;
	}

	void wyswietl()
	{
		cout << c;
	}
};

int main()
{
	Klasa1 a1; // Tworzymy obiekt z Klasa1
	Klasa2 a2; // Tworzymy obiekt z Klasa2
	a1.wczytaj(); // Wczytujemy a i b
	a2.wczytaj(); // Liczymy iloczyn ze wczytanych wcześniej a i b
	a2.wyswietl(); // Wyświetlamy iloczyn

	return 0;
}

 

komentarz 7 września 2015 przez 0xf Dyskutant (8,180 p.)
ok a co gdybym zadeklarowal c w funkcji wyswietl ?
komentarz 7 września 2015 przez Sebastian Fojcik Nałogowiec (43,020 p.)
To czas życia zmiennej 'c' byłby ograniczony do wywołania tej funkcji. Przed wywołaniem wyswietl() 'c' nie istnieje, po opuszczeniu funkcji wyswietl() 'c' nie istnieje. Słaby pomysł
:-P

Podobne pytania

0 głosów
1 odpowiedź 243 wizyt
pytanie zadane 23 marca 2021 w Python przez user125 Początkujący (400 p.)
0 głosów
2 odpowiedzi 1,262 wizyt
pytanie zadane 6 sierpnia 2019 w Python przez Dominoday Początkujący (420 p.)
0 głosów
1 odpowiedź 328 wizyt

92,547 zapytań

141,389 odpowiedzi

319,509 komentarzy

61,931 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...