Forum Sveta kompjutera

Nazad   Forum Sveta kompjutera > Test Run > Programiranje
Uputstvo Članstvo Kalendar Današnje poruke Pretraži

Programiranje Programski jezici, tehnike, alatke...

Odgovor
 
Alatke vezane za temu Vrste prikaza
Stara 24.1.2017, 10:36   #1
NEWSWEETTOFFEE
Član
 
Član od: 3.5.2012.
Poruke: 45
Zahvalnice: 16
Zahvaljeno 2 puta na 2 poruka
Određen forumom Ispisivanje sadržaja vektora koji sadrži pokazivače

Dakle, imam problem sa sledećim kodom:
Kod:
#include <iostream>

#include"Point.h"
#include"GeometricObject.h"
#include"Circle.h"
#include"Rectangle.h"
#include<vector>
#include<string>

/*
void printVector(vector<GeometricObject*> vec)
{
    for (vector<GeometricObject*>::iterator itr = vec.begin(); itr != vec.end(); itr++)
        cout << *itr << " ";
}
*/

using namespace std;

int main()
{
    try
    {
        Point x, x1=Point(5.6, 3.4);

        cout << x.getX() << ", " << x.getY() << endl
             << x1.getX() << ", " << x1.getY() << endl;
        x.setX(7.7); x.setY(2.5);
        cout << x.getX() << ", " << x.getY() << endl;

        Circle c1, c2=Circle(x1, 10);
        Rectangle r1=Rectangle(x, 6.66, 3.33), r2=Rectangle(x1, 5, 3.3);

        c1.describe();
        c2.describe();
        r1.describe();
        r2.describe();
    }
    catch(string error)
    {
        cerr << error;
    }

    try
    {
        Point x=Point(5.4, 3.2), x1=Point(6.6, 7.7);
        vector<GeometricObject*> vec;

        cout << string(30, '-') << endl << endl;

        GeometricObject *c1=new Circle(x, 4.6), *c2=new Circle(x1, 112.3),
                        *r1=new Rectangle(x, 5.6, 8.7), *r2=new Rectangle(x1, 77.7, 44.4);

        vec.push_back(c1);
        vec.push_back(c2);
        vec.push_back(r1);
        vec.push_back(r2);

        int d=vec.size();

        cout << d << endl;

        for(int i=0; i<d; i++)
            vec[i]->describe();
        //    vec.at(i)->describe();

       // for(vector<GeometricObject*>::iterator itr = vec.begin(); itr != vec.end(); itr++)
       //     cout << (*itr)->describe() << " ";
    }
    catch(string error)
    {
        cerr << error;
    }

    return 0;
}
Ne znam da pokrenem metodu 'describe()' koju 'Circle' i 'Rectangle' nasleđuju od 'GeometricObject'. Pokušao sam par stvari, ali samo pokrenem metodu iz 'GeometricObject'. Molim vas, možete li mi reći šta to ne znam da uradim kako bih rešio problem?
NEWSWEETTOFFEE je offline   Odgovor sa citatom ove poruke
Stara 24.1.2017, 12:19   #2
voodoo_
V.I.P. GNU/Linux
 
Avatar korisnika voodoo_
 
Član od: 1.11.2005.
Poruke: 11.166
Zahvalnice: 2.086
Zahvaljeno 4.923 puta na 2.859 poruka
Određen forumom Re: Ispisivanje sadržaja vektora koji sadrži pokazivače

U klasi GeometricObject, metoda describe() mora biti deklarisana kao virtual da bi program na osnovu tipa objekta, a ne tipa pokazivača, izabrao koju varijantu descibe() će da pozove.

Dakle

Kod:
class GeometricObject {
public:
    virtual void describe();
};
Ako nije virtual, onda će kompajler da prevede poziv na osnovu tipa pokazivača (u tvom slučaju GeometricObject*) i pozivaće GeometricObject::describe().
Ako jeste virtual, onda forsiraš takozvani "late binding", pa će poziv vec[i]->describe() biti razrešen tokom izvršavanja programa na osnovu tipa objekta, i pozvaće ispravan Circle::describe() ili Rectangle::describe().
voodoo_ je offline   Odgovor sa citatom ove poruke
Sledeći korisnik se zahvaljuje korisniku voodoo_ na korisnoj poruci:
NEWSWEETTOFFEE (24.1.2017)
Stara 24.1.2017, 15:42   #3
NEWSWEETTOFFEE
Član
 
Član od: 3.5.2012.
Poruke: 45
Zahvalnice: 16
Zahvaljeno 2 puta na 2 poruka
Određen forumom Re: Ispisivanje sadržaja vektora koji sadrži pokazivače

Metoda jeste definisana kao virtuelna, ali na sledeći način:
Kod:
virtual void describe() const
{
    cout << "Tip objekta: " << name << endl;
}
, gde je 'string name' jedan atribut bazne klase. Kada sam uklonio 'const' onda je program proradio kako sam i hteo. Odande odakle sam učio o ovome su korišćeni primeri gde je iza definicija virtuelnih metoda pisalo 'const = 0' ili 'const' pa sam zaključio da je to deo komande kojom kazujemo da li je metoda apstraktna ili ne. Sada znam da je potrebno samo napisati '= 0' da bi se metoda proglasila apstraktnom.
NEWSWEETTOFFEE je offline   Odgovor sa citatom ove poruke
Stara 24.1.2017, 16:09   #4
voodoo_
V.I.P. GNU/Linux
 
Avatar korisnika voodoo_
 
Član od: 1.11.2005.
Poruke: 11.166
Zahvalnice: 2.086
Zahvaljeno 4.923 puta na 2.859 poruka
Određen forumom Re: Ispisivanje sadržaja vektora koji sadrži pokazivače

'const' su metode za koje tvrdiš kompajleru da neće menjati polja klase, što nema mnogo veze sa ovim primerom. Isto tako nije obavezno da osnovna metoda bude apstraktna da bi je preklopio. U svakom slučaju, ako baš treba da bude 'const', probaj da ti i osnovna i preklopljena metoda budu 'const'.
voodoo_ je offline   Odgovor sa citatom ove poruke
Stara 24.1.2017, 17:55   #5
NEWSWEETTOFFEE
Član
 
Član od: 3.5.2012.
Poruke: 45
Zahvalnice: 16
Zahvaljeno 2 puta na 2 poruka
Određen forumom Re: Ispisivanje sadržaja vektora koji sadrži pokazivače

U ovom zadatku koji radim, ne traži se specifično da metode budu 'const' i izgleda da sam se tu negde i zeznuo jer sam nešto proglašavo 'const' a nešto nisam. Sada sam stavio da mi sve virtuelne i nasleđene metode ne budu 'const' i program radi.
Evo celog programa:

'main.cpp'
Kod:
#include <iostream>

#include"Point.h"
#include"GeometricObject.h"
#include"Circle.h"
#include"Rectangle.h"
#include<vector>

using namespace std;

int main()
{
    try
    {
        Point x, x1=Point(5.6, 3.4);

        cout << x.getX() << ", " << x.getY() << endl
             << x1.getX() << ", " << x1.getY() << endl;
        x.setX(7.7); x.setY(2.5);
        cout << x.getX() << ", " << x.getY() << endl;

        Circle c1, c2=Circle(x1, 10);
        Rectangle r1=Rectangle(x, 6.66, 3.33), r2=Rectangle(x1, 5, 3.3);

        c1.describe();
        c2.describe();
        r1.describe();
        r2.describe();
    }
    catch(string error)
    {
        cerr << error;
    }

    try
    {
        Point x=Point(5.4, 3.2), x1=Point(6.6, 7.7);
        vector<GeometricObject*> vec;

        cout << string(30, '-') << endl << endl;

        GeometricObject *c1=new Circle(x, 4.6), *c2=new Circle(x1, 112.3),
                        *r1=new Rectangle(x, 5.6, 8.7), *r2=new Rectangle(x1, 77.7, 44.4);

        vec.push_back(c1);
        vec.push_back(c2);
        vec.push_back(r1);
        vec.push_back(r2);

        int d=vec.size();

        cout << d << endl;

        for(int i=0; i<d; i++)
            vec[i]->describe();
    }
    catch(string error)
    {
        cerr << error;
    }

    return 0;
}
'Point.h'
Kod:
#ifndef POINT_H_INCLUDED
#define POINT_H_INCLUDED

using namespace std;

class Point
{
private:
    double x;
    double y;

public:
    Point(double _x=0, double _y=0)
    : x(_x), y(_y)
    {}

    double getX() { return x; }

    double getY() { return y; }

    void setX(double _x) { x=_x; }

    void setY(double _y) { y=_y; }
};

#endif // POINT_H_INCLUDED
'GeometricObject.h'
Kod:
#ifndef GEOMETRICOBJECT_H_INCLUDED
#define GEOMETRICOBJECT_H_INCLUDED

using namespace std;

class GeometricObject
{
private:
    string name;

public:
    GeometricObject(string _name)
    : name(_name)
    {
        setName(_name);
    }

    string getName() { return name; }

    void setName(string _name)
    {
        if(_name=="")
            throw string("Ime ne moze biti prazno!\n");

        name=_name;
    }

    virtual void describe()
    {
        cout << "Tip objekta: " << name << endl;
    }

    virtual double circumference() =0;

    virtual double area() =0;
};

#endif // GEOMETRICOBJECT_H_INCLUDED
'Circle.h'
Kod:
#ifndef CIRCLE_H_INCLUDED
#define CIRCLE_H_INCLUDED

#include"Point.h"

using namespace std;

class Circle : public GeometricObject
{
private:
    Point centre;
    double radius;

public:
    Circle(Point _centre=Point(0, 0), double _radius=0)
    : GeometricObject("Krug"), centre(_centre), radius(_radius)
    {
        if(radius <0)
            throw string("Radijus ne moze biti manji od 0!");
    }

    double circumference()
    {
        return 2*radius*3.14;
    }

    double area()
    {
        return radius*radius*3.14;
    }

    void describe()
    {
        cout << "Tip objekta: " << getName() << endl
             << "Centar: " << "(" << centre.getX() << ", " << centre.getY() << ")" << endl
             << "Radijus: " << radius << endl
             << "Obim: " << circumference() << endl
             << "Povrsina: " << area() << endl << endl;
    }
};

#endif //CIRCLE_INCLUDED
'Rectangle.h'
Kod:
#ifndef RECTANGLE_H_INCLUDED
#define RECTANGLE_H_INCLUDED

#include"Point.h"


using namespace std;

class Rectangle : public GeometricObject
{
private:
    Point topLeft;
    double width;
    double height;

public:
    Rectangle(Point _topLeft=Point(0, 0), double _width=0, double _height=0)
    : GeometricObject("Pravougaonik"), topLeft(_topLeft), width(_width), height(_height)
    {
        if(width<0)
            throw string("Sirina ne moze biti manja od 0!");
        else if(height<0)
            throw string("Visina ne moze biti manja od 0!");
    }

    double circumference()
    {
        return 2*(width+height);
    }

    double area()
    {
        return width*height;
    }

    void describe()
    {
        cout << "Tip objekta: " << getName() << endl
             << "Gornje levo teme: " << "(" << topLeft.getX() << ", " << topLeft.getY() << ")" << endl
             << "Sirina: " << width << endl
             << "Visina: " << height << endl
             << "Obim: " << circumference() << endl
             << "Povrsina: " << area() << endl << endl;
    }
};

#endif // RECTANGLE_H_INCLUDED
Ja sam imao verziju gde su mi metode 'describe', 'circumference' i 'area' bil 'const' u svim hederima, ali program nije radio (onaj deo gde treba da ispiše članove vektora). Pošto program radi sada kada nema nijedne 'const' metode u njemu, zašto nije radio kada su sve virtuelne i nasleđene metode 'const'?

Takođe, u tekstu zadatka piše da u klasama 'Circle' i 'Rectangle' predefinišem 'describe()' pozivajući implementaciju iz roditeljske klase, pa me zanima da li sam ja to uradio ili to znači da nekako pozovem funkciju iz bazne klase u definiciju metode u izvedenoj klasi?

Poslednja ispravka: NEWSWEETTOFFEE (24.1.2017 u 18:29)
NEWSWEETTOFFEE je offline   Odgovor sa citatom ove poruke
Sledeći korisnik se zahvaljuje korisniku NEWSWEETTOFFEE na korisnoj poruci:
voodoo_ (24.1.2017)
Stara 24.1.2017, 23:00   #6
voodoo_
V.I.P. GNU/Linux
 
Avatar korisnika voodoo_
 
Član od: 1.11.2005.
Poruke: 11.166
Zahvalnice: 2.086
Zahvaljeno 4.923 puta na 2.859 poruka
Određen forumom Re: Ispisivanje sadržaja vektora koji sadrži pokazivače

Za prvo pitanje,
http://stackoverflow.com/questions/9...tion-non-const

Za drugo, nisi uradio. Kad hoćeš da pozoveš baznu implementaciju metode, onda radiš nešto ovako:

Kod:
void Rectangle::describe() {
    GeometricObject::describe();
    // ovde ide eventualni dodatni posao
}
voodoo_ je offline   Odgovor sa citatom ove poruke
Sledeći korisnik se zahvaljuje korisniku voodoo_ na korisnoj poruci:
NEWSWEETTOFFEE (25.1.2017)
Odgovor

Bookmarks sajtovi


Vaš status
Ne možete postavljati teme
Ne možete odgovarati na poruke
Ne možete slati priloge uz poruke
Ne možete prepravljati svoje poruke

BB kod: uključeno
Smajliji: uključeno
[IMG] kod: uključeno
HTML kod: isključeno


Slične teme
tema temu započeo forum Odgovora Poslednja poruka
Koji je najbolji program za puštanje multimedijalnog sadržaja? Denmla Video/TV softver 22 8.3.2010 11:31


Sva vremena su po Griniču +2 h. Sada je 23:21.


Powered by vBulletin® verzija 3.8.7
Copyright ©2000–2024, vBulletin Solutions, Inc.
Hosted by Beograd.com