Przekazywanie wskazników w konstruktorze

0

Witam, na jutro musze to zrobic niestety nie wiem jak sie do tego zabrac. Mam przepudowac to co nizej, tak aby user byl tworzony w c_USER w konstruktorze i przekazywany do obiektu c_ORDER za pomoca wskaznika. Nie umiem tego dokladnie przekazac nawet :(

Tak tworze obiekty

c_ORDER* order = new c_ORDER();
c_USER* user1 = new c_USER();

Tak wygladaja pliki naglowkowe:
user.h

#pragma once

class c_USER 
{
	private:
	__int16 user;

	public:
	c_USER();
	~c_USER();
	void setUser(__int16 argUser);
	__int16 getUser();
};

i user.cpp

#pragma once
#include "stdafx.h"

c_USER::c_USER() {};
c_USER::~c_USER() {};

void c_USER::setUser(__int16 argUser)
{ user = argUser; }

__int16 c_USER::getUser()
{ return user; }

order.h

#pragma once

class c_ORDER
{
	public:
	c_ORDER();
	~c_ORDER();
};

order.cpp

#pragma once
#include "stdafx.h"
#include "order.h"

c_ORDER::c_ORDER() {}
c_ORDER::~c_ORDER() {}

Potrzebuje tego na jutro, nie dam rady powtorzyc wszystkiego o wskaznikach samemu wiec prosze o pomoc bardziej doswiadczonych :/ Blagam...

0

wykladowca dal mi takie cos jako przyklad (z ksiazki kaczmarskiego)

// klasa serca
class CHeart { /* ... */ };
// bazowa klasa zwierząt
class CAnimal
{
// (pomijamy nieistotne, pozostałe składowe)
protected:
CHeart* m_pSerce;
public:
// konstruktor i destruktor
CAnimal() { m_pSerce = new CHeart; }
~CAnimal() { delete m_pSerce; }
}

No i tlumaczyl ze to ma byc jakos przekazywane w konstruktorze czy cos, naprawde jestem w potrzebie :O Mam nadzieje ze wy wiecie wiecej ode mnie

0

@do newbie

karczi napisał(a)

tak aby user byl tworzony w c_USER

wcale, że nie bo to jest bez sensu, pomyśl troche, obiekt ma tworzyć samego siebie w konstruktorze? to się skończy nieskończonym wywoływaniem konstuktora => przepełnienie stosu => wysypanie się programu

masz zrobić tak, aby obiekt c_USER ma być tworzony w konstruktorze c_ORDER jak już, bo c_ORDER ma zawierać w sobie odnośnik(wskaźnik) do c_USERa

czego nie rozumiesz?

0

No pewnie masz racje ;O

No nie wiem jak sie za to zabrac, nie rozumiem wskaznikow bo ich jeszcze nie przerobilem samemu w domu i jestem w ich temacie zielony, przejrzalem fragmenty kodow gdzies po sieci ale duzo mi to nie dalo ;O Wiem mniej wiecej co mam zrobic ale nie wiem jak sie za to zabrac - w ogóle nie wiem jak to zrobic. Wskazniki to mi sa znane tylko z tego ze uzywam ich przy tworzeniu obiektu a potem sie odwoluje wskaznik->metoda

;/

0
karczi napisał(a)

Wiem mniej wiecej co mam zrobic ale nie wiem jak sie za to zabrac
To wytłumacz jakoś po ludzko, za co są odpowiedzialne te klasy i co je łączy, co ma się dziać w tym konstruktorze. Po twoim pierwszym poście nie idzie się domyślić.

0

W dotychczasowym programie nie mialem klasy c_USER i plikow user.h i user.cpp, a metody getUser i setUser ktore sie tam znajduja znajdowaly sie w klasie c_ORDER.

Wykladowca stwierdzil ze chcialby widziec wiecej powiazan miedzy klasami i obiektami, i nakazal rozdzielenie na dwie klasy. Wytlumaczyl to jakos tak, aby jedna odpowiadala za tego usera i przekazywala jako wskaznic nazwe tego usera do klasy c_ORDER. Lepiej teraz? Wole nie dopowwiadac i nie rekonstruowac tego co ejszcze powiedzial bo wyjdzie jeszcze gorzej ;)

i jako wzor ktory moze mi pomoc wskazal mi ten kod ktory zamiescilem w 2gim poscie.

Moge powiedziec tak: Chce mieć klase c_ORDER przy której tworzeniu, stworzy Ci sie automatycznie obiekt klasy c_USERi dane tego usera beda widoczne w klasie c_ORDER? - lepiej? tylko nie wiem jak to zrealizowac

0

Chodzi o relację krzyżową, tj:

class c_ORDER
{
private:
        c_USER *user;
public:
        c_ORDER()
        {
                user = new c_USER(this); //tworzymy user'a i zapisujemy jego wskaźnik
        }
        ~c_ORDER()
        {
                delete user; //przy niszczeniu order'a niszczymy też powiązanego z nim user'a
        }
};

class c_USER 
{
private:
        c_ORDER *order;
public:
        c_USER(c_ORDER *order)
        {
                this->order = order; //zapisujemy wskaźnik do order'a, który stworzył user'a
        }
};
0
karczi napisał(a)

Wykladowca stwierdzil ze chcialby widziec wiecej powiazan miedzy klasami i obiektami
Zawsze wydawało mi się, że powinno się dążyć do minimalizacji powiązań między klasami.

Co do przykładu, z książki jest zrozumiały (bo nazewnictwo jest jasne i precyzyjne, więc i cel klas jest zrozumiały).
W twoim przypadku nazewnictwo niewiele mówi, jaka ma być relacja między klasami, ergo nie wiadomo jak przenieść rozwiązanie z przykładu na twój program.

@adf88: zachodzę w głowę jak doszedłeś. Widzę założenie, że c_ORDER tworzy (zawiera) obiekt c_USER, a z tym wskaźnikiem na "parent'a" to raczwej mu namieszasz w głowie.
Na dodatek mnie klapka otwiera się w drugą stronę, że c_USER tworzy c_ORDER, no ale tu właśnie pytanie co to właściwie ma robić?

0
MarekR22 napisał(a)
karczi napisał(a)

Wykladowca stwierdzil ze chcialby widziec wiecej powiazan miedzy klasami i obiektami
Zawsze wydawało mi się, że powinno się dążyć do minimalizacji powiązań między klasami.

Wiesz chodzi o to ze chca nas nauczyc wiec nie daza do optymalizacji kodu na tym etapie :D

@adf88, dzieki aczkolwiek wydaje mi sie e to nie do konca to o co mi chodzilo - jest to moja wina bo nie potrafie nazwac mojego problemu ani wyjasnic jak ma byc rozwiazany. Napisalem do wykladowcy, mam nadzieje ze szybko odpisze i bede mogl udzilic dodatkowych informacji ktore beda przydatne...

Dziek iza cierpliowsc i dotychczasowa pomoc!

0

Albo sproboje jeszcze w ten sposb, tutaj ( http://www.box.net/shared/mqcgijd0rg ) jest link do mojego programu, tak bedzie chyba najszybciej a nie bede wklejal poszarpany kod tutaj.

Chodzi o to zeby wszystko co zwiazane z uzytkownikiem wydzielic z c_ORDER do nowej klasy, a nastepnie powiazac ja za pomoca wskaznika wlasnie na nowo z klasa c_ORDER. Chodzi o to zeby byla mniedzy nimi jakas zaleznosc a nie dwie klasy nie powiazane ze soba.

Wiem, jestem beznadziejny :O

0

Powinieneś zrobić właśnie to co napisałeś. W klasie zamówienia, masz tą osobę i jej numer. Te dwie wartości wywalasz do klasy c_USER i gitara gra:

class c_USER
{
	private:
	__int16 user;
	__int32 phone;
	
	void setUser(__int16 argUser);
	__int16 getUser();
	void setPhone(__int32 argPhone);
	__int32 getPhone();
};
	
class c_ORDER
{
	private:
	c_USER* _user;
	
	public:
	c_ORDER(c_USER* user=NULL):_user(user){}
	~c_ORDER();
	__int16 app_width, app_height;
	c_USER* getUser() { return _user; }
};

int main()
{
	c_USER user;
	c_ORDER order(&user);
}

Jak już tak jest mowa o poprawności klas i ich związkach to akurat zamówienie ma raczej mało wspólnego z wymiarami aplikacji

PS. Z tym beznadziejny to trochę przesadzasz ;) ale skąd taki sposób nadawania nazw wziąłeś to nie wiem.

0

a jake jest dziwne nazwenictwo? ;D
generalnei robie aplikacje okienkowa, setUser zczytuje wartosc texBoxa, a getUser zwraca (enkapsulacja)

btw w c_USER nie musi byc konstruktora/destruktora? :O
zwraca mi mase bledow niestety, moze nie umiem rozdzielic kodu na *.cpp i *.h?
zamiescilem wyzej gdzis moj program, dalbys rade na nim to zrobic, tak zebym mogl przestudiowac jak to dziala na gotowym i dzialajacym kodzie? :O

0

wow, to co reVis napisal zaczyna wchodzic w zycie :) mam juz "tylko" 2 bledy i 2 warningi :) Warningi moga byc, ale musze te errory zlikwidowac :D

1>c:\users\karczi\desktop\projekt - kopia\projekt\order_form.h(496) : warning C4800: 'c_USER *' : forcing value to bool 'true' or 'false' (performance warning)
1>.\projekt.cpp(10) : error C2664: 'c_ORDER::c_ORDER(c_USER *)' : cannot convert parameter 1 from 'c_USER' to 'c_USER *'
1>        No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1>panel_blind.cpp
1>order_form.cpp
1>c:\users\karczi\desktop\projekt - kopia\projekt\order_form.h(496) : warning C4800: 'c_USER *' : forcing value to bool 'true' or 'false' (performance warning)
1>order.cpp
1>.\order.cpp(6) : error C2511: 'c_ORDER::c_ORDER(void)' : overloaded member function not found in 'c_ORDER'

Teraz po rozdzieleniu na pliki *.h i *cpp to wyglada tak:
user.h:

#pragma once

class c_USER
{
	private:
		__int16 user;
	public:
		void setUser(__int16 argUser);
		__int16 getUser();
};

user.cpp:

#pragma once
#include "stdafx.h"
#include "user.h"

void c_USER::setUser(__int16 argUser)
{ user = argUser; }

__int16 c_USER::getUser()
{ return user; }

order.h:

#pragma once
#include "user.h"

class c_ORDER
{
	private:
	c_USER* _user;
	__int32 phone;

	public:
	  c_ORDER(c_USER* user=0):_user(user){} //NULL zamiast 0 nei dziala
	~c_ORDER();
	__int16 app_width, app_height;

	 c_USER* getUser();

	void setPhone(__int32 argPhone);
	__int32 getPhone();
};

order.cpp:

#pragma once
#include "stdafx.h"
#include "order.h"

c_ORDER::c_ORDER() 
{
	app_width = 1030;
	app_height = 580;
}

c_ORDER::~c_ORDER() {}

void c_ORDER::setPhone(__int32 argPhone)
{ phone = argPhone; }

__int32 c_ORDER::getPhone()
{ return phone; }

obiekty tworze globalnie:

c_ORDER* order = new c_ORDER(*user);
c_USER* user = new c_USER();

i w kazdej formi gdze je potrzebuje jest:

extern c_ORDER* order;
extern c_USER* user;

Helpa potrzebuje w zlikwidowaniu errorkow i powinno zadowolic wykladowce :O
I co z metodami getUser, setUser? Nie sa juz potrzebne? Chcialbym zeby to jakos tak dzlalao jak dzialalo ze po uruchomieniu aplikacji samemu sie wpisuje do textBox1 jakies tam imie czy login - da rade to jakos polaczyc?
</cpp>

0

Wykladowca odpisal:
"Powinien Pan zdefiniować klasę użytkownika, zamówienia, produktu i formularza. Wszystko powinno być ze sobą połączone. Żeby połączenia były wykonane w sposób właściwy, powinny być wykorzystane w tym celu wskaźniki. Każda klasa powinna być zbudowana zgodnie z zasadami hermetyzacji."

Zamowienie i produkt powiedzmy ze juz mam, chodzi wiec o klase usera nad ktora pracujemy tutaj wlasnie :)

0

Wiesz, akurat umiejętność czytania i interpretacji błędów (tym bardziej własnych) jest istną podstawą.
Pierwszy oznacza, że przekazujesz użytkownika, a nie wskaźnik na niego. Usuń gwiazdkę i będzie ok:

c_ORDER* order = new c_ORDER(user);

Drugi natomiast mówi, że w pliku cpp jest definicja funkcji której nie ma w nagłówku. Konkretnie chodzi o konstruktor.

//wstaw w order.h zamiast starego konstruktora
c_ORDER(c_USER* user=0);
//wstaw w order.cpp na początku zamiast c_ORDER::c_ORDER() 
c_ORDER(c_USER* user) : _user(user)
{
    app_width = 1030;
    app_height = 580;
}

A na Twoim miejscu nie bagatelizowałbym tych ostrzeżeń. Ale trudno coś powiedzieć bez danych lini. Chociaż może tylko VC panikuje.

0

Proboje samemu neutralizowac bledu, w wielu przypadkach szukanei w necie i na msdnie dziala, plus metoda prob i bledow - niestety czasem brak doswaidczenia ;(

co wlasciwie daje to?

: _user(user)

i dlaczego kazesz wywolywac konstruktor w pliku cpp w ten sposob? mnie uczono tak poslugiwac sie konstruktorami i destruktorami:

klasa::klasa() {} // konstruktor
klasa::~klasa() {} //destruktor

zrobilem jak kazales i:

1>.\order.cpp(5) : error C2143: syntax error : missing ')' before '*'
1>.\order.cpp(5) : error C2143: syntax error : missing ';' before '*'
1>.\order.cpp(5) : error C2059: syntax error : ')'
1>.\order.cpp(5) : error C2470: 'user' : looks like a function definition, but there is no parameter list; skipping apparent body
1>.\order.cpp(5) : error C2065: 'user' : undeclared identifier

-------- niech dodam:
order.h

#pragma once
#include "user.h"

class c_ORDER
{
	private:
	c_USER* _user;

	public:
	 c_ORDER(c_USER* user=0);
	~c_ORDER();
	__int16 app_width, app_height;

	 c_USER* getUser();
};

order.cpp

#pragma once
#include "stdafx.h"
#include "order.h"

c_ORDER(c_USER* user) : _user(user)
{
	app_width = 1030;
	app_height = 580;
}

c_ORDER::~c_ORDER() {}
(...)
0

Raz: sprawdź co to jest lista inicjalizacyjna konstruktora w C++
Dwa: Istnieją różne konstruktory, nie tylko bezparametrowe. Żeby było śmieszniej to Twój konstruktor ma teraz dualny charakter. Dlaczego to już zapraszam do lektury jakiegoś kursu.

//mozesz wywołać tak:
c_ORDER* o = new c_ORDER();
//jak i:
c_ORDER* o = new c_ORDER(user);

Trzy: Zapomniałem dodać zakres

//order.cpp
c_ORDER::c_ORDER(c_USER* user) : _user(user)
{
        app_width = 1030;
        app_height = 580;
}

Powodzenia :)

0

tez tak wczesniej kombinowalem ale wyskakiwaly bledy, jednak pomyslalem nad nimi troche i juz smiga :) poczytalem troche o liscie inicjalizacyjnej, mam nadzieje ze sie przyda! jednak caly czas nie wiem po kiego grzyba jest to wykozystane w tym wypadku i co to dokladnie robi :P

I w zasadzie mam jeszcze jedno wazne pytanie: czy moglbys teraz wytlumaczyc co dokladnei sie dzieje jak uruchamiam program? Chcialem to samemu przesledzic ale obawiam sie ze gubie po drodze jakies istotne informacje np. jaka role odgrywa w tym wszystkim klasa c_USER i do czego w tej chwili przydaja sie metody setUser i getUser

Przedtem one odpowiadaly za 'sciagniecie' danej z textBoxa i 'wywalenie' jej do labela, kozystajac z enkapsulacji - a czy teraz to ejst jakos z reszta powiazane czy rownie dobrze mogloby tego nie byc?

Okazalo sie ze wskazniki to fajna sprawa, obiecuje ze po sesji doczytam o nich ile sie da, bo laatwiaja zycie :)

Dzieki za dotychczasowa pomoc :)

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