1

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.

  • 1
    Does this answer your question? [What is object slicing?](https://stackoverflow.com/questions/274626/what-is-object-slicing) – Lukas-T Sep 22 '22 at 11:46
  • 3
    Why does `FamousPainting` inherit from `Painting` **and** have a `Painting` member? – 463035818_is_not_an_ai Sep 22 '22 at 11:47
  • there are a lot of issues in the code you posted. I just read `isPaintingFamous` and for some reason it requires a Painting to be painted by Degas and Monet and Picasso and Rembrandt to be considered as famous, that doesnt look right. Please read about [mcve] and try to remove stuff from your code taht is not relevant to the one specific issue you want to ask about. – 463035818_is_not_an_ai Sep 22 '22 at 11:54
  • Your code says "a famous painting is a kind of painting that also has a painting of its own". You should probably read some more about inheritance in your favourite C++ book. (Your code also says "a painting is only famous if it's by a painter whose name is all of Degas and Monet and Picasso and Rembrandt at the same time", so brush up on your logic, too.) – molbdnilo Sep 22 '22 at 12:02

1 Answers1

1

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".

Frodyne
  • 3,547
  • 6
  • 16
  • Thanks, memorization is the furthest from understanding and application. I should get used to understanding and application rather than being direct with "the end justifies the means". Hard to balance learning/understanding and performing well at school – Alex Variance Sep 22 '22 at 13:26