在C ++中使用多态而不是继承的实际优势[关闭]

问题描述 投票:-6回答:2

使用C ++中的多态性而不仅仅使用纯继承有什么好处,因为在我看来,我不能用多态来实现我只能继承的东西。同样在两种方式中我都可以使用虚拟功能。是否存在多态性可以通过仅使用继承来执行无法访问的情况?

这两个例子(第一个 - 多态性,第二个纯粹的继承)让我得到了相同的结果,所以我想知道还有什么可以为我提供多元化,这是通过正常继承来实现的。

多态性代码:

#include <iostream>
using namespace std;
class Kryptonians
{
public:
    void setPower(int p) {power = p;}
    void gotHit(int h){power -=h;}
    virtual void displayPower(){std::cout << "power is: " << power << "\n";}

protected:
    int power;
};

class Supergirl: public Kryptonians
{
public:
   void displayPower(){
       std::cout << "Supergirl's power is: " << power << "\n";}
};

class Superman: public Kryptonians
{
public:
    void displayPower(){
        std::cout << "Superman's power is: " << power << "\n";}
};

int main()
{
    Supergirl sup;
    Superman super;
    Kryptonians *supergirl = &sup;
    Kryptonians *superman = &super;

    supergirl->setPower(100);
    supergirl->displayPower();

    superman->setPower(100);
    superman->gotHit(50);
    superman->displayPower();
    supergirl->displayPower();
}

更多的不良代码:

#include <iostream>
using namespace std;
class Kryptonians
{
public:
    void setPower(int p) {power = p;}
    void gotHit(int h){power -=h;}
    virtual void displayPower(){std::cout << "power is: " << power << "\n";}

    protected:
    int power;
};

class Supergirl: public Kryptonians
{
public:
    void displayPower(){
        std::cout << "Supergirl's power is: " << power << "\n";}
};

class Superman: public Kryptonians
{
public:
    void displayPower(){
        std::cout << "Superman's power is: " << power << "\n";}
};

int main()
{
    Supergirl supergirl;
    supergirl.setPower(100);
    supergirl.displayPower();

    Superman superman;
    superman.setPower(100);
    superman.gotHit(50);
    superman.displayPower();

    supergirl.displayPower();
}

我的问题是关于为什么要使用多态,当一个人可以很好地避免使用它,并限制自己只使用继承。正如user463035818所述,基本上不存在多态可以做一些使用继承无法到达的事情的情况。据我所知,使用polymprphism是首选的设计模式?

c++ inheritance polymorphism
2个回答
2
投票

至少在C ++中,使用继承的主要原因是多态性。还有一种称为“实现继承”的东西,但它作为一般规则不赞成。

多态的规范示例将涉及一个虚函数,该函数在基类中声明并在派生类中实现:

class interface { 
public:
    virtual void foo() = 0;
};

class implementation : public interface { 
public:
    virtual void foo() override {
        // do something useful here
    }
};

在这种情况下,基类实际上根本没有实现foo,它只是声明了一个接口,因此任何与该接口一起使用的代码都可以使用该基类的任何衍生物。

实现继承主要适用于您有许多派生类,这些派生类在相同的常规事物上都有轻微变化的情况,因此您可以在案例类中实现常见行为,并且每个派生类仅实现与其不同的区域共同的基础。

C ++中实现继承的一个众所周知的例子是std::iterator。这是一个包含虚函数的基类(因此没有多态)。它的唯一目的是提供迭代器应该提供的一些typedefs。这些类型通常都是相关的,因此派生类通常可以将单个模板参数传递给基类,并获得所有必需的typedefs:

class my_iterator : public std::iterator<std::output_iterator_tag, void, void, void, void> {
    // ...
};

这样可以避免迭代器的实现者输入如下代码:using size_type = std :: size_t;使用difference_type = std :: ptr_diff_t;使用value_type = T;使用reference = T&;使用指针= T *;

它确实节省了一些打字 - 但不是很多,而且它节省的几乎都是简单的锅炉板。

然而,如上所述,这通常是不赞成的 - 实际上,std::iterator已被正式弃用,因此它可能会从该标准的某些未来版本中消失。


0
投票

多态性

在计算机科学中,多态性是一种编程语言特性,它允许以统一的方式处理不同数据类型的值。

例如:

void foo(bar& b) {
   b.do_something();
};

处理不同类型的对象同样称为多态。 b可以是任何类型,只要它继承bar

遗产

继承是面向对象编程中的系统,它允许对象支持由前类型定义的操作,而无需提供自己的定义。它是面向对象编程中多态性的主要向量

例如:

struct bar {
    virtual void do_something() = 0;
    virtual ~bar(){}
};

struct foobar1 : bar {
    virtual void do_something() override {
        std::cout << "muh";
    }
};

struct foobar2 : bar {
    virtual void do_something() override {
        std::cout << "meh";
    }
};

不同的类型可以继承相同的基类,以便可以多态使用它们。

是否存在多态性可以通过继承使用无法访问的情况?

没有。

嗯,是。

tempaltes的一些用法可以被认为是编译时多态性。如果你对编译时多态性感兴趣,你应该看看CRTP

© www.soinside.com 2019 - 2024. All rights reserved.