C++ 遗传与多态性c++;

C++ 遗传与多态性c++;,c++,C++,我读了很多关于遗传和多态性的书,但我仍然无法区分它们之间的区别 据我所知,继承是(例如,基类的派生类继承方法和方法重写也可以执行)那么什么是多态性呢?遗传和多态性都有意义吗 请纠正我,因为我知道我错了。感谢多态性允许您在继承的父类之间来回变形类。以下是合法的,如果狗和猫类继承自动物 void takes_animal(Animal &animal) { } Dog dog; Cat cat; takes_animal(dog); takes_animal(cat); 多态性允许您在继

我读了很多关于遗传和多态性的书,但我仍然无法区分它们之间的区别

据我所知,继承是(例如,基类的派生类继承方法和方法重写也可以执行)那么什么是多态性呢?遗传和多态性都有意义吗


请纠正我,因为我知道我错了。感谢

多态性允许您在继承的父类之间来回变形类。以下是合法的,如果狗和猫类继承自动物

void takes_animal(Animal &animal) { }

Dog dog;
Cat cat;
takes_animal(dog);
takes_animal(cat);

多态性允许您在继承的父类之间来回变形类。以下是合法的,如果狗和猫类继承自动物

void takes_animal(Animal &animal) { }

Dog dog;
Cat cat;
takes_animal(dog);
takes_animal(cat);

用farmer的话说,多态性是指在不知道实际实现的情况下使用“基类”(在某些情况下称为接口)的情况。继承可以与多态一起使用,也可以不与多态一起使用(即,当您使用继承但始终知道您正在处理的对象的特定类时,即使它是从其他对象继承的,也不是多态性)。但是多态性不能在没有继承的情况下使用(它只是停止了任何意义)。

用farmer的话说,多态性是指在不知道实际实现的情况下使用“基类”(在某些情况下称为接口)的情况。继承可以与多态一起使用,也可以不与多态一起使用(即,当您使用继承但始终知道您正在处理的对象的特定类时,即使它是从其他对象继承的,也不是多态性)。但是多态性不能在没有继承的情况下使用(它只是不再有任何意义)。

关于继承,你是对的,但它并没有那么简单。重载和重写也是继承的重要功能。然而,多态性是关于创建多态数组的,比如,若父类是水果,苹果是对象,那个么您可以将对象定义为水果类型并调用常规函数。另外,创建纯虚拟函数将阻止父类生成其实例。

您的继承是正确的,但并没有那么简单。重载和重写也是继承的重要功能。然而,多态性是关于创建多态数组的,比如,若父类是水果,苹果是对象,那个么您可以将对象定义为水果类型并调用常规函数。另外,创建纯虚拟函数将阻止父类生成其实例。

继承是一种实现技术。多态性是一种 您可以使用它实现的一个方面。(这是 不是唯一的事情。例如,从
std::iterator
与多态性无关。)

继承是一种实现技术。多态性是一种 您可以使用它实现的一个方面。(这是 不是唯一的事情。例如,从
std::iterator
与多态性无关。)

在这种情况下,我们有继承,但没有多态性:

struct SimpleBase {
  int i;
  int get() const { return i; }
};

struct SimpleDerived: public SimpleBase {
  int get() const { return i + 7; }
};
SimpleBase的实例(或指向它的引用或指针)总是如此,派生类不能更改其行为。例如:

int foo(SimpleBase const &obj) { return obj.get(); }
将始终调用
SimpleBase::get
,即使传入派生类型的实例


相反,使用多态性,派生类可以用自己的版本重写基类方法:

struct PolyBase {
  int i;
  virtual int get() const { return i; }
};

struct PolyDerived {
  int get() const { return i + 7; }
};

int foo(PolyBase const &obj) { return obj.get(); }
现在,foo根据传入的派生类型调用不同的方法,而不知道它是哪个派生类型

因此,使用多态性,整个类型家族可以共享一个公共接口,您可以编写一次在该接口上运行的代码,而不必知道所有不同的派生类型


上面显示的多态性形式是运行时多态性:它生成代码,确定每个虚拟函数在运行时调用哪个实现

还有编译类型多态性,它根本不需要继承,而是使用模板

假设您想编写一个排序容器(比如std::map)——您不想将其限制为存储特定的数据类型,但您确实需要某种方法来比较两个元素,以确定哪个更大

运行时方法可能提供一个抽象基类,如

struct LessThanComparable {
  virtual bool operator< (LessThanComparable const &) const = 0;
};
struct lessthan可比{
虚拟布尔运算符<(小于可比常数&)常数=0;
};

并要求您要放入容器中的每种类型,从中派生并实现
操作符在这种情况下,我们有继承但没有多态性:

struct SimpleBase {
  int i;
  int get() const { return i; }
};

struct SimpleDerived: public SimpleBase {
  int get() const { return i + 7; }
};
SimpleBase的实例(或指向它的引用或指针)总是如此,派生类不能更改其行为。例如:

int foo(SimpleBase const &obj) { return obj.get(); }
将始终调用
SimpleBase::get
,即使传入派生类型的实例


相反,使用多态性,派生类可以用自己的版本重写基类方法:

struct PolyBase {
  int i;
  virtual int get() const { return i; }
};

struct PolyDerived {
  int get() const { return i + 7; }
};

int foo(PolyBase const &obj) { return obj.get(); }
现在,foo根据传入的派生类型调用不同的方法,而不知道它是哪个派生类型

因此,使用多态性,整个类型家族可以共享一个公共接口,您可以编写一次在该接口上运行的代码,而不必知道所有不同的派生类型


上面显示的多态性形式是运行时多态性:它生成代码,确定每个虚拟函数在运行时调用哪个实现

还有编译类型多态性,它根本不需要继承,而是使用模板

假设您想编写一个排序容器(比如std::map)——您不想将其限制为存储特定的数据类型,但您确实需要某种方法来比较两个元素,以确定哪个更大

运行时方法可能提供一个抽象基类,如

struct LessThanComparable {
  virtual bool operator< (LessThanComparable const &) const = 0;
};
struct lessthan可比{
虚拟布尔运算符