简体   繁体   中英

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM