Search code examples
c++oopinheritancepolymorphismabstraction

Override a base class member in derived class C++


I can't seem to overwrite the base class member (Painting) value for the derived class FamousPainting.

Things I have tried:

  • virtual function
  • creating new setter function in derived class
  • change derived class constructor signature

I am at a loss of what to do now

#include <iostream>
#include <string>
#include <vector>
using namespace std;

class Painting
{
   protected:
      string title;
      string artist;
      int value;
   public:
       Painting();
       Painting(string, string);
       // copy constructor
       Painting(string,string,int);
       void showPainting();
       void setData();
       string getTitle();
       string getArtist();
       int getValue();
       //virtual void setValue();
};

Painting::Painting()
{

}

Painting::Painting(string name, string painter)
{
    name = title;
    artist = painter;
    value = 400;
}

Painting::Painting(string _title,string _artist, int _value)
{
   title = _title;
   artist = _artist;
   value = _value;
}

void Painting::setData()
{
     cout << "Enter painting's title: ";
     cin >> title;
     cout << "Enter artist: ";
     cin >> artist;
     value = 400;
}

/*
void Painting::setValue()
{
   value = 400;
}
*/

void Painting::showPainting()
{
   cout << title << " done by " << artist << " cost $" << value << endl;
}

string Painting::getTitle()
{
  return title;
}

int Painting::getValue()
{
  return value;
}

string Painting::getArtist()
{
  return artist;
}

class FamousPainting: public Painting 
{
   private:
      Painting painting;
   public:
      FamousPainting(string, string,int);
      //void setValue();
};

FamousPainting::FamousPainting(string name, string painter, int val) : painting(name,painter,val) {}

/*
void FamousPainting::setValue()
{
   this->value = 25000;
}
*/

bool isPaintingFamous(Painting &p)
{
  bool isFamous = true;
  const int NUM = 4;
  string artists[NUM] = {"Degas","Monet","Picasso","Rembrandt"};
  int x;
  for(x = 0; x < NUM; x++)
    if(p.getArtist() != artists[x])
       isFamous = false;
  return isFamous;
}

int main()
{  

   vector<Painting> listofpainting;
   vector<FamousPainting> listoffpainting;

   for(int i = 0; i < 2; i++)
   {
        Painting temp;
        temp.setData();
        if(isPaintingFamous(temp))
        {
          FamousPainting tempF(temp.getTitle(),temp.getArtist(),25000);
          listoffpainting.push_back(tempF);
        }
        listofpainting.push_back(temp);
   }

   for(Painting paint: listofpainting)
   {
      paint.showPainting();
   }

   for(FamousPainting fpaint: listoffpainting)
   {
      fpaint.showPainting();
   }

    return 0;
}

The output:

Enter painting's title: Hime
Enter artist: Mary
Enter painting's title: Sophistry
Enter artist: Monet
Hime done by Mary cost 400
Sophistry done by Monet cost 400

For FamousPainting, I cannot overwrite the value to 25000 which is the requirement of the Lab.


Solution

  • Several issues:

    class FamousPainting: public Painting  // <- Inherits from Painting
    {
       private:
          Painting painting;  // <- Contains a Painting called "painting"
    

    You should pick one of the two. Either FamousPainting IS a Painting and should inherit, or it CONTAINS a Painting and should not inherit. I suspect you want the inheritance and not the member.

    This also bites you later in the FamousPainting constructor:

    FamousPainting::FamousPainting(string name, string painter, int val)
    : painting(name,painter,val) {}
    

    This is a nice delegating constructor, unfortunately it does not actually initialize the FamousPainting itself - instead it only initializes the Painting member it contains. Change it to:

    : Painting(name,painter,val) {} // <- delegates to the parent class
    

    It is a bit subtle because you named the Painting member painting.

    Next the logic in the isPaintingFamous function is wrong. This is one of the situations where it helps to step through the code with a debugger, so you can see how the variable values change at every step.

    But basically you start off saying: "This is famous", then you check the names, and as soon as any of them fail, you change your mind and set it to not famous. So a Rembrandt fails the Monet check and then forever stays "not famous".