Help with Vectors and Dynamic Objects

Discussion in 'C++' started by acheron05, May 14, 2006.

  1. acheron05

    acheron05 Guest

    Hi there,

    Hopefully I won't fit the stereotype of the typical student posting his
    assignment to be written for him, but I am quite stuck. If anyone could
    give me some help in how to create dynamic objects (which inherit from
    a base class) and storing them in a vector, it would be absolutely
    wonderful at this point. I think from there I might be able to sculpt
    the rest of the program without (too much) trouble. I'll post what I've
    been trying to do so far and also the header file.

    Thanks in advance for any help.

    #include "a3.h"

    string queryInput;

    // Don't forget to supply your information in the function below . . .
    void displayInfo()
    {
    cout << "----------------------------------------" << endl;
    cout << "Assignment 3 Semester 1 2006" << endl;
    cout << " Submitted by: Donald, Duck, 00000000" << endl;

    cout << "----------------------------------------" << endl;
    cout << endl << queryInput << endl;
    }

    //Driver for the Media/Movie classes for assignment 3,
    //2006, Semester 1
    int main()
    {

    cout<<"Media Database Control Program v0.4b\n\n"<<
    "Please enter the title of the media record you wish to view: ";
    getline(cin, queryInput);
    cout<<"\n\nAccessing record for "<<queryInput<<"...."<<endl<<endl;

    // Call the global function to print Student/Group names and IDs
    displayInfo();

    // Container of Media pointers
    vector<Media *> mediaItems;

    Media::readFromFile("/a3-input.txt", mediaItems);

    // Display to the screen
    for(unsigned i = 0; i < mediaItems.size(); i++)
    {
    mediaItems->display(); // use the polymorphic display function
    cout<<endl;
    }

    // Work out total stock value, StockInfo functions are inaccessible
    // unless we recast
    int value = 0;
    int nItems = 0;

    for(unsigned i=0; i<mediaItems.size(); i++)
    {
    Movie *ptr = static_cast<Movie *>(mediaItems);
    value += ptr->getPrice() * ptr->getNumberInStock();
    nItems += ptr->getNumberInStock();
    }

    cout << "Total stock value of " << nItems << " items is " << value <<
    endl;
    return 0;
    }

    // Implement your member function classes here

    Movie::Movie()
    {

    }

    void display()
    {
    }

    void Movie::setDirector(const string& d)
    {
    director = d;
    }

    void Movie::setTime(int t)
    {
    time = t;
    }

    void Movie::setQuality(int q)
    {
    quality = q;
    }

    void Media::setTitle(const string& t)
    {
    title = t;
    }

    void Media::getData(ifstream& fin)
    {

    }

    void Media::readFromFile(const string& filename, vector<Media*>&
    mediaItems)
    {

    mediaItems.resize(20);

    cout<<filename<<endl;

    char tempData[10000];
    string recordData;
    ifstream dataBase("/a3-input.txt");

    while(recordData != "ENDOFRECORDS")
    {
    int i = 0;

    dataBase.getline(tempData, 10000);
    recordData = tempData;

    if(recordData == "Movie")
    {
    Movie* mediaItems;
    mediaItems.setDirector(recordData);

    i++;
    }
    }

    dataBase.close();
    }


    Here is the header file....

    /* Assignment A3, Header file, See A3.doc for specification.
    *
    * Class Hierarchy:
    *
    * Media StockItem
    * | |
    * +--------------------------+
    * |
    * V
    * Movie
    * |
    * V
    * +------------+-------------+
    * | |
    * V V
    * Revised Foreign
    *
    *
    * *** DO NOT CHANGE THIS FILE ***
    */

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>

    using namespace std;

    // Base class to provide stock control info
    class StockItem{
    public:
    void readStockInfo( ifstream& fin ); // read in price and
    numberInStock
    void displayStockInfo();
    int getPrice(){ return price; }
    int getNumberInStock(){ return numberInStock; }
    protected:
    int price; // in cents
    int numberInStock;
    };

    // Abstract base class for all media products
    class Media{
    public:
    virtual ~Media(){}
    virtual void getData( ifstream& fin) = 0; // get a single record
    virtual void display() = 0; // print out to cout the details of a
    record

    void setTitle( const string& t);

    // Open stated file, and read in records into the vector of Media
    // pointers (which is passed by reference) allocating a new object
    // of the right type, dynamically, to the i'th pointer
    static void readFromFile( const string& filename, vector<Media*>& m);


    protected:
    string title;
    };

    // Declaration/definition of Movie
    class Movie : public Media, public StockItem{
    public:
    Movie();
    void setDirector( const string& d );
    void setTime( int t = 0);
    void setQuality( int q = 0 );

    virtual void display(); // print out to cout the details of a
    record
    virtual void getData( ifstream& fin); // get a single record

    protected:
    string director;
    int time; // in minutes
    int quality; // 0 (bad) to 4 (excellent)

    // These are optional but allow code reuse for polymorphs display
    // and getDataprotected:
    void commonDisplay();
    void getCommonData( ifstream& fin);

    };

    // Declaration of Foreign
    class Foreign : public Movie {
    public:
    void setLanguage( const string& lang );
    virtual void display(); // see descriptions in Movie
    virtual void getData( ifstream& fin);
    private:
    string language; // language of a foreign film
    };

    // Declaration of Revised
    class Revised : public Movie{
    public:
    void setRevisedTime( int rt = 0);
    void setChanges( const string& ch );
    virtual void display(); // see descriptions in Movie
    virtual void getData( ifstream& fin);
    private:
    int revisedTime; // the revised running time in minutes
    string changes; // description of any changes made
    };
    acheron05, May 14, 2006
    #1
    1. Advertising

  2. acheron05

    Dennis Jones Guest

    "acheron05" <> wrote in message
    news:...
    > Hi there,
    >
    > Hopefully I won't fit the stereotype of the typical student posting his
    > assignment to be written for him, but I am quite stuck. If anyone could
    > give me some help in how to create dynamic objects (which inherit from
    > a base class) and storing them in a vector, it would be absolutely
    > wonderful at this point. I think from there I might be able to sculpt
    > the rest of the program without (too much) trouble. I'll post what I've
    > been trying to do so far and also the header file.



    It's generally considered bad practice to store raw pointers in a vector (or
    most any container for that matter), though I suppose in the context of a
    beginning C++ class it's not completely unreasonable.


    To create a "dynamic" object, use the 'new' operator:

    Movie *pMovie = new Movie; // create a "Movie" object and assign its
    pointer to 'pMovie'


    Storing objects in a vector is typically done using vector's 'push_back'
    member function:

    std::vector<Movie *> Movies;
    Movies.push_back( pMovie ); // add the 'pMovie' pointer to the vector

    This should be enough to get you started.

    - Dennis
    Dennis Jones, May 14, 2006
    #2
    1. Advertising

  3. acheron05

    benben Guest

    Not that your code is poor but can't you at least indicate which line
    your problem is? Certainly you don't want us to guess your problem.

    Or even better, just post the relevant bit to demonstrate what you want
    to do.

    Remember, the purpose of your post is to help us help yourself.

    Regards,
    Ben
    benben, May 14, 2006
    #3
  4. acheron05

    acheron05 Guest

    Yep, sorry about that... Heres my basic overview:

    The program reads in an input file of Media records and creates
    specific objects for each of these 4-6 line records, based on their
    type. For example, If a string is read from the input file and matches
    "Movie" then create a new dynamic object "Movie" which inherits
    properties from the base class "Media". Same for "Foreign" and
    "Revised" types of records aswell. Pointers to these objects (as per
    this assignment's specification) then need to be stored within the
    container:

    vector<Media *> mediaItems;

    I have the infrastructure in place to cycle through the input
    "database" and read in the lines of text, plus the flow control to
    distinguish between the different types of records. I'm just not sure
    how to create new objects of the given type and store pointers to them
    within the vector. I'm also not sure how the vector gets passed back to
    the calling function either.

    Hopefully this will make a bit more sense! Thanks very much.
    acheron05, May 14, 2006
    #4
  5. acheron05

    benben Guest

    acheron05 wrote:
    > Yep, sorry about that... Heres my basic overview:
    >
    > The program reads in an input file of Media records and creates
    > specific objects for each of these 4-6 line records, based on their
    > type. For example, If a string is read from the input file and matches
    > "Movie" then create a new dynamic object "Movie" which inherits
    > properties from the base class "Media". Same for "Foreign" and
    > "Revised" types of records aswell. Pointers to these objects (as per
    > this assignment's specification) then need to be stored within the
    > container:
    >
    > vector<Media *> mediaItems;


    Aha, this information makes it all clearer doesn't it?

    Here I provide a simple function from which you can build your solution
    upon:

    Media* get_media_from_stream(std::istream& input)
    {
    std::string media_type;
    input >> media_type;

    if (media_type == "Foreign")
    return new Foreign_movie(input);

    if (media_type == "Movie")
    return new Movie(input);

    // ...

    return 0;
    }

    Notice that you need to design a constructor for the media types so that
    they can take an istream as argument.

    Regards,
    Ben
    benben, May 14, 2006
    #5
  6. acheron05

    acheron05 Guest

    I've implemented my code to create new objects for the readFromFile
    member function, but am now getting an error message come up:

    Undefined symbols:
    vtable for Movie

    Is this due to the virtual functions within the Media and Movie classes
    and incorrect constructors?

    Thanks again
    acheron05, May 16, 2006
    #6
  7. Do you have deconstructors defined for your classes?

    That usually is what my problem is if I get an undefined vtable error.

    Gemma

    "acheron05" <> wrote in message
    news:...
    > I've implemented my code to create new objects for the readFromFile
    > member function, but am now getting an error message come up:
    >
    > Undefined symbols:
    > vtable for Movie
    >
    > Is this due to the virtual functions within the Media and Movie classes
    > and incorrect constructors?
    >
    > Thanks again
    >
    Gemma Fletcher, May 18, 2006
    #7
  8. Gemma Fletcher wrote:
    > "acheron05" <> wrote in message
    > news:...
    > > I've implemented my code to create new objects for the readFromFile
    > > member function, but am now getting an error message come up:
    > >
    > > Undefined symbols:
    > > vtable for Movie
    > >
    > > Is this due to the virtual functions within the Media and Movie classes
    > > and incorrect constructors?

    >
    > Do you have deconstructors defined for your classes?
    > That usually is what my problem is if I get an undefined vtable error.


    Gemma,
    Please learn to quote correctly on Usenet. See
    http://en.wikipedia.org/wiki/Top-post for more informations. And it's
    "destructor", not "deconstructor".

    Acheron05 (OP),
    Always check the FAQ before posting. You'd be surprised.
    http://www.parashift.com/c -faq-lite/strange-inheritance.html#faq-23.10


    Jonathan
    Jonathan Mcdougall, May 18, 2006
    #8
  9. <Snip>
    >>
    >> Do you have deconstructors defined for your classes?
    >> That usually is what my problem is if I get an undefined vtable error.

    >
    > Gemma,
    > Please learn to quote correctly on Usenet. See
    > http://en.wikipedia.org/wiki/Top-post for more informations. And it's
    > "destructor", not "deconstructor".
    >
    > Acheron05 (OP),
    > Always check the FAQ before posting. You'd be surprised.
    > http://www.parashift.com/c -faq-lite/strange-inheritance.html#faq-23.10
    >
    >
    > Jonathan


    Jonathan,

    Yes, I unfortunately posted this before the top-posting problem was brought
    to my attention in another thread :)

    Won't happen again.

    Not sure why I said deconstructors - it was late. *blush*
    Gemma
    Gemma Fletcher, May 19, 2006
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. bigbinc
    Replies:
    3
    Views:
    399
    Michael Borgwardt
    Nov 18, 2003
  2. Ninan Thomas
    Replies:
    1
    Views:
    441
    =?ISO-8859-1?Q?Juan_Antonio_Dom=EDnguez_P=E9rez?=
    Oct 22, 2003
  3. Jim
    Replies:
    8
    Views:
    368
    James Kanze
    Jan 16, 2008
  4. Replies:
    3
    Views:
    695
    Shadowman
    Mar 26, 2008
  5. Guest
    Replies:
    0
    Views:
    439
    Guest
    Sep 14, 2005
Loading...

Share This Page