Hi i am so lost and stressed please can some help me. My question is how do i code the follwoing

• Constructor: Copy The copy constructor should check the validity of the Entry object parameter through the use of the isValid method and copy the valid objects media and entertainment objects through the use of the createCopy functions.
• Constructor: 2 argument The 2-argument constructor takes a media and entertainment object as parameters. A copy should be made of the parameters through the createCopy function, if they are valid and stored in the current Entry object.
Entry class

Entry::Entry():_media(NULL),_entertainment(NULL){}
Entry::Entry(const Entry& entry):_media(NULL),_entertainment(NULL)
{
 
}
Entry::Entry(const Media& media, const Entertainment& entertainment)
{
 
}
Entry::~Entry()
{
delete _media;
delete _entertainment;
}
Media * Entry::getMedia()
{
 
return _media;
}
const Media * Entry::getMedia() const
{
 
return _media;
}
Entertainment * Entry::getEntertainment()
{
return _entertainment;
}
const Entertainment * Entry::getEntertainment() const
{
 
return _entertainment;
}
bool Entry::isValid() const
{
 
return _media != NULL && _entertainment != NULL;
 
}
bool Entry::operator ==(const Entry& obj) const
{
if (getEntertainment()->getEntertainmentType() != obj.getEntertainment()->getEntertainmentType())
{
return false;
}
if (getMedia()->getMediaType() != obj.getMedia()->getMediaType())
{
return false;
}
if (getEntertainment()->getTitle() != obj.getEntertainment()->getTitle())
{
return false;
}
 
return true;
}
bool Entry::operator !=(const Entry& entry) const
{
return !(*this==entry);
}

Entry header file

class Entry
{
Entertainment *_entertainment;
Media *_media;
public:

Recommended Answers

All 15 Replies

i guess i dont know how to to do is pass them by value and implement a copy constructor on those classes

Scrap that above quick reply i have done my copy constructor is this oksy

Entry::Entry(const Entry& entry):_media(NULL),_entertainment(NULL)
{

if(entry.isValid())
{
_media->createCopy();
_entertainment->createCopy();
}
}

Thanks for the code tags, but use of indentation would make the code a whole lot easier to read!

Per your instructions the copy contstructor in your third post looks appropriate, though you'll need to declare and define the createCopy() functions somewhere. I suspect that the createCopy() functions should be sent the appropriate values from entry, else how will they know what to copy into the appropriate members. Within the createCopy() functions I suspect you will want to use deep copy rather than shallow copy to copy the information given that _media and _entertainment are both pointers.

Yeah i have two virtual functions (createCopy()) in the media and entertainment class and normal create copy functions in the bases classes extending media and entertainment that create a copy of itself on the heap and return a pointer reference to it.
Like:

Entertainment * Game::createCopy(void) const
{

              return new Game(*this); 

}

Oh yeah i have like 6 virtual constructors 2 of which are pure (in media and entertainment) do i need to create desturctors for them? Just the pure ones

quote=NSta;278471]Yeah i have two virtual functions (createCopy()) in the media and entertainment class and normal create copy functions in the bases classes extending media and entertainment that create a copy of itself on the heap and return a pointer reference to it.
Like:

Entertainment * Game::createCopy(void) const
{
 
             return new Game(*this); 
 
}

so in the game class my copy constructor is as follows (
The copy constructor must call the base class copy constructor and pass the parameter from the copy constructor to the base class copy constructor. The copy constructor must also copy the attributes from the other object.
)

Game::Game(const Game& game):Entertainment(game)
{
  _cdKey = game._cdKey;
  _sysRequirements =game._sysRequirements; 
  game.createCopy();
}
Entry::Entry(const Entry& entry):_media(NULL),_entertainment(NULL)
{
    if(entry.isValid())
    {
        if ( entry._media != NULL )
        {
            _media = entry._media->createCopy();
        }

        if ( entry._entertainment != NULL )
        {
            _entertainment = entry._entertainment->createCopy();
        }
    }
}

media and entertainment are abstract classes

Unless my memory is as cloudy as the weather this morning, you can't declare objects of an abstract class. Therefore, the Entry class could not have member variables of an abstract class type, though it can inherit attributes associated with an abstract base class. If the attribute is a member function, then that function needs to be overridden in the current class. However, that doesn't seem to be what is wanted in the instructions:

>>copy the valid (Entry) objects media and entertainment objects through the use of the createCopy functions.

Are you sure the Media and Entertainment classes are supposed to be abstract? If you are, then I'll have to bow out and let someone else provide assistance.

Posting the Media or Entertainment class code would be helpful, too.

public:
 /**
  * Default constructor for the Media class
  */
 Media(void);
 /**
  * Copy constructor for the Media class
  *
  * @param audio Audio object
  */
 Media(const Media& media);
 /**
  * Returns the barcode of the current instance
  *
  * @returns barcode
  */
 const string& getBarcode(void) const;
 
 virtual string getMediaType(void) const = 0;
 
 /**
  * Returns the speed of the current instance
  *
  * @returns speed
  */
 const string& getSpeed(void) const;
 /**
  * Sets the barcode of the current instance
  *
  * @param barcode
  */
 void setBarcode(const string& barcode);
 /**
  * Sets the speed of the current instance
  *
  * @param speed
  */
 void setSpeed(const string& speed);
 /**
  * Compares the supplied parameter to the current instance
  *
  * @param obj Media object to compare to
  * @returns true if the current instance is the same as the supplied parameter
  */
 bool operator ==(const Media& obj) const;
 /**
  * Calls the operator== and returns its inverse
  *
  * @param media Media object to compare to
  * @returns true if the current instance is different to the supplied parameter
  */
 bool operator !=(const Media& media) const;
 
 virtual Media * createCopy(void) const = 0;
 /**
  * Reads in values of the instance variables from the console
  *
  * @returns 0 if the read worked, -1 if it failed
  */
 virtual int read(void);
 /**
  * Reads in values of the instance variables from a tokeniser object
  *
  * @param tok Tokeniser object
  * @returns 0 if the read worked, -1 if it failed
  */
 virtual int read(Tokeniser& tok);
 /**
  * Writes instance variables to the console
  *
  * @returns 0 if the write worked, -1 if it failed
  */
 virtual int write(void) const;
 /**
  * Writes instance variables to a file stream
  *
  * @param outf Output file stream
  * @returns 0 if the write worked, -1 if it failed
  */
 virtual int write(ofstream& outf) const = 0;

I have tried this in my constructor it compiles but does not seem right to me any thoughts?

Entry::Entry(const Media& media, const Entertainment& entertainment)
{
 
  _media = media.createCopy();
  _entertainment =   entertainment.createCopy();
  Entry *entry;
  entry = new Entry(media, entertainment);
}
Entry *entry;
  entry = new Entry(media, entertainment);

What are you trying to do here? You've already assigned the private members of the class (_media and _entertainment). And once the function returns, the newly allocated Entry object is lost (memory leak)

Entry *entry;
  entry = new Entry(media, entertainment);

What are you trying to do here? You've already assigned the private members of the class (_media and _entertainment). And once the function returns, the newly allocated Entry object is lost (memory leak)

I am trying to store in the current Entry object.

Again I ask if it is necessary to create the Media class as abstract.? It is a compile time error to try to instantiate an object of an abstract data type.

struct A
{
   int data;
   virtual void createCopy(const A & rhs) const = 0;
};

A a;   //error, cannot instantiate an object of type A since A is an abstract data type.

class B
{
   A a;  //error, cannot instantiate an object of type A even as a data member
};

However, you can declare a pointer to abstract class and use that to demonstrate polymorphism.

class C : public A
{
    C() : data(0) {}
    C(int i) : data(i) {}
    void createCopy(const A & rhs) { data = rhs.data};
};

int main()
{
   A * pA;  //this is a pointer to type A, not an A object.  This is legal.
   C c(5);
   C c1;
   pA = &c1;
   pA->createCopy(c);  //copy data from c into c1 using the virtual function called createCopy() and the pointer to base class A, which happens to be abstract.  This is a pretty lame example, but I think it 
makes the point.  
}

In your case I think you need something like this, though:

class A
{
   int data;
   
   public:
   A(const A & rhs) 
   {
       createCopy(const A & rhs);
   }
   void getData() { return data};
   void createCopy(const A & rhs) {data = rhs.getData();}
};

class B
{
    //basically same a class A, don't make A or B abstract
};

class C
{
   A a;
   B b;
   
   public:
   A(const C & rhs)
   {
      if(isValid(rhs))
      {
        a.createCopy(rhs);
        b.createCopy(rhs);
      }
    }
    bool isValid(const C & rhs) { //whatever};
};

However, in your case it doesn't appear as if the Entry class is derived from the Media and the Entertainment class based on what's posted so far, so I see no reason to have the Media and the Entertainment class abstract, unless it is required in some other portion of your instructions.

Thanks i finnaly did it

Entry::Entry(const Entry& entry):_media(NULL),_entertainment(NULL)
{

if(entry.isValid())
{
if ( entry._media != NULL )
{
_media = entry._media->createCopy();
}
if ( entry._entertainment != NULL )
{
_entertainment = entry._entertainment->createCopy();
}
}
}
Entry::Entry(const Media& media, const Entertainment& entertainment)
{
Entry entry;
if (entry.isValid())
{
_media = entry.getMedia()->createCopy();
_entertainment = entry.getEntertainment()->createCopy();
}

}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.