1

I have a class named House that extends from a class named City.

class City
{
public:
    string get(){
        return "San Francisco"
    }
};

class House : public City
{
public:
    string get(){
        return "My House"
    }
};

int main()
{
    City world[2];
    House h;
    world[0] = h;
    cout << world[0].get() << endl;
}

The result I want back is "My House", but instead I get "San Francisco". Why is this and how do I fix it? I thought that if you named a function the same as a function existing in the inherited class, then that function would always be called.

Cup of Java
  • 1,769
  • 2
  • 21
  • 34

2 Answers2

1

for what you looking for you should use virtual keyword, like this:

class City
{
public:
    virtual ~City() {}//you need virtual destructor  
    virtual string get(){
        return "San Francisco"
    }
};

also you need to use pointers instead of value to achieve what you want:

City *world[2];
world[0] = new House;
cout << world[0]->get() << endl; 
delete world[0];
fghj
  • 8,898
  • 4
  • 28
  • 56
  • Correct answer, but I think OP wanted an explanation of "why" as well. It might be helpful if you added this. – Brad Nov 13 '15 at 06:02
1

Which function will be called is determined at compile time. For your case, City::get() will always be called because the type of array's element is City.

Note that world[0] = h; will cause object slicing, House will be copied(sliced) as City.

If you want dynamic polymorphism, you need to call the member funtion via pointer or reference. And you need to make the member function virtual. Such as

class City
{
public:
    virtual string get() {
        return "San Francisco";
    }
    virtual ~City() {}
};

class House : public City
{
public:
    virtual string get() override {
        return "My House";
    }
};

int main()
{
    City* world[2];
    House h;
    world[0] = &h;
    cout << world[0]->get() << endl;
}
Community
  • 1
  • 1
songyuanyao
  • 169,198
  • 16
  • 310
  • 405