英文:
Why does this call to `getNoise` use the base class implementation and not the subclass implementation?
问题
问题
我的理解是,通过在基类中将 getNoise
声明为虚拟函数,然后在任何子类中重写它,我们可以实现多态性。然后,通过指针的向量,我们存储基类的地址,用于调用诸如 getNoise
之类的方法。
有人能告诉我为什么我的代码没有做到这一点吗?
代码
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
class Animals {
private:
std::string noise = "None";
public:
Animals() = default;
virtual ~Animals() = default;
virtual std::string getNoise() {
return noise;
}
};
class Duck : public Animals {
private:
std::string noise = "Quack!";
public:
using Animals::Animals;
std::string getNoise() override {
return noise;
}
};
class Dog : public Animals {
private:
std::string noise = "Bark!";
public:
using Animals::Animals;
std::string getNoise() override {
return noise;
}
};
class AnimalsContainer {
public:
std::vector<Animals *> animals;
Animals *front;
AnimalsContainer() {
Duck duck;
Dog dog;
animals.push_back(&duck);
animals.push_back(&dog);
front = animals[0];
}
~AnimalsContainer() = default;
};
int main() {
AnimalsContainer animals;
cout << animals.front->getNoise() << endl;
}
预期输出
我期望得到
Quack!
但我得到了
None
请问有什么问题?
英文:
The problem
My understanding was that we could achieve polymorphim by making getNoise
virtual in the base, and then overriding it in any subclasses. Then via a vector of pointers, we store the address of the base classes which are used to call methods on such as getNosie
below.
Could anybody tell me why my code doesn't do this?
The code
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
class Animals {
private:
std::string noise = "None";
public:
Animals() = default;
virtual ~Animals() = default;
virtual std::string getNoise() {
return noise;
}
};
class Duck : public Animals {
private:
std::string noise = "Quack!";
public:
using Animals::Animals;
std::string getNoise() override {
return noise;
}
};
class Dog : public Animals {
private:
std::string noise = "Bark!";
public:
using Animals::Animals;
std::string getNoise() override {
return noise;
}
};
class AnimalsContainer {
public:
std::vector<Animals *> animals;
Animals *front;
AnimalsContainer() {
Duck duck;
Dog dog;
animals.push_back(&duck);
animals.push_back(&dog);
front = animals[0];
}
~AnimalsContainer() = default;
};
int main() {
AnimalsContainer animals;
cout << animals.front->getNoise() << endl;
Expected output
I'm expecting
Quack!
But I'm getting
None
答案1
得分: 2
"std::string noise"应该只在基类中声明,而不是在子类中声明。应该在子类的构造函数中设置噪声值。
英文:
"std::string noise" should only be declared in the base class, not in the subclasses. Set the noise value in the constructors of the subclasses instead.
答案2
得分: 1
为什么不使用指针:
Duck* duck = new Duck();
Dog* dog = new Dog();
animals.push_back(duck);
animals.push_back(dog);
而不是
Duck duck;
Dog dog;
animals.push_back(&duck);
animals.push_back(&dog);
然后你可以在析构函数中销毁它们:
~AnimalsContainer() {
for (Animal* a : animals) {
delete a;
}
}
如果你真的需要在基类中使用字符串 "none"。
当然,原始指针是为了简单起见,你也可以考虑使用智能指针。
英文:
Why dont't you use pointers:
Duck* duck = new Duck();
Dog* dog = new Dog();
animals.push_back(duck);
animals.push_back(dog);
Instead of
Duck duck;
Dog dog;
animals.push_back(&duck);
animals.push_back(&dog);
You can then destroy them on the destructor:
~AnimalsContainer() {
for (Animals* a : animals) {
delete a;
}
}
If you really need noise string "none" in the base class.
Of course the raw pointers are for simplicity, you should maybe use smart pointers.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论