obiekty i funkcje

0

Hej;
Stworzylem klase, a nastepnie dwa obiekty. Niestety nie umiem zmiennych z tych obiektow wsadzic do funkcji.
Klasa zawodnik:
plik .h

class zawodnik
{
    int nr_zaw;
    string typ_zaw;
    double zaw_x;

public:

    int nr;
    string typ;
    double poz_x;

       void zapamietaj (int nr, string typ, double poz_x);



    void matryca_poz(double zaw_x);
};

 

plik .cpp

#include "zawodnik.h"
using namespace std;

void zawodnik::zapamietaj (int nr, string typ, double poz_x)
{
      nr_zaw=nr;
    typ_zaw=typ;
    x_zaw=poz_x;
}
void zawodnik::matryca_poz(zaw_x)
{
    ...
}

 

plik main:


zawodnik wr, qb;


      wr.zapamietaj (80,"WR",3200);
      qb.zapamietaj (13,"qb",3000);

   matryca_poz(wr);
   matryca_poz(qb);




 

Nie umiem w funkcji matryca_poz wpisac zmiennej zaw_x dla obiektów wr i qb.
Czy potraficie mi pomóc?
Dzieki

0

Przypadkiem nie miało być : zaw_x=poz_x zamiast x_zaw=poz_x;

 void zawodnik::zapamietaj (int nr, string typ, double poz_x)
{

     nr_zaw=nr;
    typ_zaw=typ;
    x_zaw=poz_x; // tutaj 
   
}
 
1
void matryca_poz(double zaw_x);

Deklarujesz, że funkcja przyjmuje argument typu double. Co więcej jest to metoda klasy zawodnik.

zawodnik wr, qb;
matryca_poz(wr);
matryca_poz(qb);

A potem przekazujesz do niej obiekty typu zawodnik (a powinieneś double), traktując ją jako wolno stojącą funkcję.

Pytanie tak naprawdę brzmi: co chcesz zrobić?

0

twonek, chciałbym do funkcji matryca_poz przekazac argument double zaw_x o wartosci 3200 dla obiektu wr, a nastepnie 3000 dla obiektu qb.
probowalem wczesniej taki zapis:

qb.matryca_poz(double zaw_x);
wr.matryca_poz(double zaw_x);

tez bez sukcesu:(

0
qb.matryca_poz(3000);
wr.matryca_poz(3200);
0

dzieki Marszal.
Jednak ja bym chcial aby nie wpisywac do funkcji stalej wartosci. Chce zeby to byla zmienna ustalana poprzez tworzenie roznych obiektów.

0
double wartosc = 3000;
qb.matryca_poz(wartosc);
0

A nie da sie tego polaczyc jakos z konstruktorem? Chce zeby poprzez deklaracje obiektu byla wyznaczana wartosc zmiennej x_zaw. I potem byla przesylana do funkcji.
Straszna ze mnie maruda:) i jeszcze nie douczona:)

1
#include <iostream>
using namespace std;

struct foo
{
	double value;
	foo(double bar) : value(bar) {}
};

void foobar(double x)
{
	cout << x << endl;
}

int main() 
{
	foo object(3454.4);
	foobar(object.value);
	
	return 0;
}
0

Dzieki :) chyba o to mi chodziło.
Bede musial poczytac o strukturach. bo troche tego nie jarze:)
Ale wyglada ze mi pomogłeś:)

0

twonek a czy struktury moga dziedziczyc jak klasy??

0

Nie

1

Oczywiście.

0
polsky777 napisał(a):

twonek a czy struktury moga dziedziczyc jak klasy??

struktura to jest dokładnie to samo co klasa...

0

Chlopaki to czemu ludzie uzywaja klas? z pespektywy ( strasznie ograniczonej) mojego programu wychodzi ze struktury sa bardziej praktyczne.
na pewno jest jakis haczyk?

1

Używaj struktur do reprezentowania jakiś POD i podobnych, bo w inne miejsca wchodzi z buciorami enkapsulacja.

0

Spartan; Enkapsulacja - chodzi o to ze w strukturach jest ryzyko ze strace kontrole nad zmiennymi ( przez przypadek je pzomieniam) a w klasie zmienne charaktreryzujace obiekt sa private?
Przepraszam dopeiro sie ucze i nie znam Waszej koderskeij nomenklatury:( Co to POD?

2

Tak naprawdę to kwestia konwencji i przyzwyczajeń. To co potrafi klasa, umie też struktura. Chcesz, żeby pola struktury były prywatne? Użyj specyfikatora private.

Przyjęło się, że struktury używamy do grupowania danych, bez jakiejś większej logiki. POD - plain old data.

struct point
{
    double x;
    double y;
};

Natomiast w momencie gdy mamy dane (z różnymi poziomami dostępu) oraz logikę przetwarzającą te dane, to używamy klasy.

class Point
{
public:
    Point();
    Point(double x, double y);

    double distance(const Point& rhs);

private:
    double x;
    double y;
};
0

Niestety dalej mój program nie działa:(
Nie umiem wsadzic argumentu zaw_x do funkcji matryca_poz :(
Tak wyglada plik glowny:


 zawodnik napad_1( 80 );
    zawodnik * p_napad_1 = & napad_1;
    p_napad_1->nr_zaw = 80;
    p_napad_1->typ_zaw = "WR";
    p_napad_1->zaw_x = 3200;


    double x_ball=3259;

    ile=x_ball;
    matryca[ile]=1;
    cout<<matryca[ile]<<"  matryca "<<ile<<endl;



   zawodnik.matryca_poz(p_napad_1->value_x, matryca);



a to struktura:



struct zawodnik


{

    int nr_zaw;
    string typ_zaw;
    double zaw_x;


    int value_nr;
    string value_typ;
    double value_x;

    zawodnik (double value_x) : zaw_x(value_x) {}
    zawodnik (int value_nr) : nr_zaw(value_nr) {}
    zawodnik (string value_typ) : typ_zaw(value_typ) {}


    void matryca_poz(double x, int *matryca)

    {
        int ile =x;

        matryca[ile]=2000;

        cout<<matryca[ile]<<"  matryca klasa"<<ile<<endl;
    }



};

A to komunikat o błedzie:

D:\C++\mecz\main.cpp|66|error: expected unqualified-id before '.' token

blad dotyczy wiersza:

 
zawodnik.matryca_poz(p_napad_1->value_x, matryca);

( dzieki twonek)

0

Niestety dalej mój program nie działa:(
Nie umiem wsadzic argumentu zaw_x do funkcji matryca_poz :(
Tak wyglada plik glowny:


 zawodnik napad_1( 80 );
    zawodnik * p_napad_1 = & napad_1;
    p_napad_1->nr_zaw = 80;
    p_napad_1->typ_zaw = "WR";
    p_napad_1->zaw_x = 3200;


    double x_ball=3259;

    ile=x_ball;
    matryca[ile]=1;
    cout<<matryca[ile]<<"  matryca "<<ile<<endl;



   zawodnik.matryca_poz(p_napad_1->value_x, matryca);



a to struktura:



struct zawodnik


{

    int nr_zaw;
    string typ_zaw;
    double zaw_x;


    int value_nr;
    string value_typ;
    double value_x;

    zawodnik (double value_x) : zaw_x(value_x) {}
    zawodnik (int value_nr) : nr_zaw(value_nr) {}
    zawodnik (string value_typ) : typ_zaw(value_typ) {}


    void matryca_poz(double x, int *matryca)

    {
        int ile =x;

        matryca[ile]=2000;

        cout<<matryca[ile]<<"  matryca klasa"<<ile<<endl;
    }



};

A to komunikat o błedzie:

D:\C++\mecz\main.cpp|66|error: expected unqualified-id before '.' token

blad dotyczy wiersza:

 
zawodnik.matryca_poz(p_napad_1->value_x, matryca);

( dzieki twonek)

1
zawodnik.matryca_poz(p_napad_1->value_x, matryca);

zawodnik to nazwa klasy, a nie obiektu. Do wywołania niestatycznej metody potrzebujesz obiektu.

zawodnik * p_napad_1 = & napad_1;

jaki jest sens tworzenia tego wskaźnika?

0
polsky777 napisał(a):

Chlopaki to czemu ludzie uzywaja klas? z pespektywy ( strasznie ograniczonej) mojego programu wychodzi ze struktury sa bardziej praktyczne.
na pewno jest jakis haczyk?

Jak to bardziej praktyczne? Haczyk, nie ma haczyka.
Stroustrup(twórca C++) w książce "C++ Programming Language":
//"Styl który wybierzesz zależy wyłącznie od okoliczności i gustu. Ja przeważnie preferuje struktury dla klas w których wszystkie zmienne są publiczne. Myślę o takich klasach jako "nie do końca prawidłowe, zwyczajne struktury danych"
Funkcjonalnie nie ma żadnej różnicy poza domyślnym prywatny/publiczny"
//
Rzecz jasna inicjalizacja zmiennej przed wywołaniem konstruktora też jest dla klas ;)

Zatem lepiej jest używać klas i dobrą praktyką jest wręcz nadużywać zabezpieczeń. Dodatkowo w postaci słowa const dla wartości zwracanych przez funkcje i parametrów. Nawet jeśli zdarzy się wyjątkowa konieczność je siłowo ominąć przez const_cast<typ&> lub reinterpret_cast<typ> lub w C++11 słowem override. W przypadku private i protected można ominąć blokadę poprzez friend i to znacznie lepsza praktyka selektywnie się dzielić niż udostępnianie co popadnie publicznie.

Notabene funkcjonalność inicjalizacji została dodana w specyfikacji C++98r a dopiero w specyfikacji C++11 dodano możliwość wywołania konstruktora jednego typu przed wywołaniem konstruktora innego typu(analogicznie do inicjalizacji zmiennych po : ) co umożliwiło tworzenie łańcuszków wywołań konstruktorów zapożyczony z C#. Zmniejszyła się ilość duplikatów. Dawniej nie było i ucząc się wywoływałem konstruktor w ciele konstruktora.. co było koszmarnym błędem wynikającym z niezrozumienia. Wprowadzono bo tak powinno działać zgodnie z intuicją. Z prostą zmienną w ciele konstruktora nie ma problemu po co rzesadzać - definiuj w domyślnym konstruktorze bo pamięć jest już zaalokowana dla niej. Jeśli trafisz na problem w inicjalizacji domyślnych wartości dla klas w ciele rodzica to stosuj trik : Konstruktor klasy zostanie wywoływany przed wywołanien konstruktora rodzica inaczej byłby dopiero po lub natrafił być na Acces Violation.. ale pewnie jeszcze nie wiesz o co mi chodzi ;)

Zmierzam do tego żebyś stworzył w miare możliwości drugiego konstruktora który ma możliwość podania parametrów domyślnych i pokombinowania z obecnością dwóch. (Tak by nie duplikować kodu) To zaprocentuje w doświadczeniu.

Wracając do podstaw - w Twoim kodzie rzuca się najmocniej to że tworzysz funkcję zapamiętaj ale zmienne upubliczniłe. Standardowo tkwisz na etapie C i struktur(czyli programistycznego komunizmu wałkowanego przez nauczycieli) Raz ze względów na bezpieczeństwo dwa ze względu na obsługę klasy w aplikacji wielowątkowej lepiej stworzyć funkcję const o podobnej nazwie co zmienna, a realną zabezpieczyć przed nadpisaniem w dziale protected(dodając do ksywki np f_nazwa). Warto stosować const dla takich funkcji by zabezpieczyć siebie się przed pomyłką potraktowania funkcji odczytu jako zmiennej lvalue. Tak niewiele żeby uniknąć pułapek na przyszłość. Kolejnym etapem który wprowadzono 10 lat temu via Borland i Microsoft jest ichniejsze property. W C++ warto więc zamiast być leniwym nauczyć się "nadużywania" template i stosowania klas z przeładowanymi operatorami () i = to zastąpi proste zmienne znacznie ciekawiej i umożliwi operowanie jakby była np. integerem. Umożliwiając wbudowanie w nią mechanizmu dostępu wielowątkowego czy nawet zapisu historii zmian.. Różne cuda można wymyślać s jeśli się będzie szanowało prywatność obiektów(nie obchodził problemów słowem public:) to się później zwróci z nawiązką wtedy można powiedzieć - korzystam z C++ a nie C.

Nie wiem czy mnie zrozumiesz, ogólnie chciałem przekazać żebyś przy okazji nauki pośpiesznie olał kanony prawione przez nauczycieli i zapoznał się z klasami (chociaż pewnie w sumie ten program jest efektem szkoły) Oni najpierw uczą C później C++ nauczając nie C++ tylko jakieś pokraki w rozkroku. Do konstrukcji własnych obiektów również zalecam tworzenie pochodnych STL więc jak najszybsze zapoznanie się z template i dzidziczeniem i co za tym idzie też przeładowania operatorów i virtual. Stosowania jak często to jest możliwe bo pięknie dało by się zastosować nawyki ułatwiając pisanie. W szkołach każdy jest zmuszany do bycia Scottem Mayersem ewentualnie tworzenia własnego Boosta jakbyśmy żyli w latach 80 ubiegłego stulecia... Nie to żebym Ci narzucał wszystko naraz, ale jeśli masz czas to dobra możliwość nauki która zaprocentuje. struct.. jasne że bez różnicy ale jednak to symboliczna kotwica złych nawyków. To tyle od czlowieka który z nimi walczy :)

0

stasinek: sam się uczę... Stąd pewnie te brzydkie nałogi. Troche internet, troche fora, troche "symfonia c++" . Ot taki wynik tego bigosu.
Niestety nie wiele z Twojej rady zrozumialem:( za wysokie progi. Nic chyba tylko przysiasc jeszcze raz do "symfonii" :)
Oki postaram sie jednak uzyc klas w miejsce struktur ( tak zrozumialem Twoja radę).

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