【问题标题】:Can we achieve polymorphism through const function?我们可以通过 const 函数实现多态性吗?
【发布时间】:2013-07-10 04:22:05
【问题描述】:

我们可以通过 const 函数实现多态吗? 我的意思是一个函数 a() 和另一个函数 a()const 的行为是多态的吗?

void func(int a){}
void func(int a)const {}

【问题讨论】:

  • 不,它们必须具有相同的签名。
  • 这取决于你所说的多态性。重载或Ad hoc polymorphism 是一种多态性。然而,当人们谈论 C++ 中的多态性时,他们通常指的是通过虚函数(也称为 subtype polymorphism)进行动态调度,但事实并非如此。
  • 我认为你需要解释一下你所说的多态是什么意思,因为答案可能是任何一种方式。
  • 对于多态性需要是虚拟的。您可以使用 C++11 中的 override 关键字检查是否是这种情况
  • @JustinMeiners 对于 virtual 或运行时多态性需要是虚拟的。但是还有更多类型的多态性。函数重载为多态提供了另一种方式。

标签: c++ polymorphism


【解决方案1】:

正如@chris 解释的那样,“不,它们必须具有相同的签名”。

【讨论】:

    【解决方案2】:

    这不是多态性。这是函数重载。

    您可能会将 重载覆盖 混淆。

    函数重载是两个同名但签名不同的函数。您发布的代码是一个示例。构成签名的函数部分包括参数列表和方法的const 限定。值得注意的是,函数的返回类型不是函数签名的一部分。

    函数覆盖是使用关键字virtual创建的。具有相同的名称和相同的*签名。覆盖背后的基本思想是,如果您只有指向基类的指针,则能够调用派生类的特殊函数。这是一个例子:

    class Foo
    {
    public: 
      virtual std::string GetIt() const { return "FOO" }
    };
    
    class Bar : public Foo
    {
    public:
      std::string GetIt() const { return "BAR"; }
    };
    
    int main()
    {
      Foo* that = new Bar;
      cout << that->GetIt();
    }
    

    即使指针是指向Foo 的指针,程序也会输出“BAR”。


    *“同一个签名”:实际上是协变签名。

    【讨论】:

    • 函数重载是一种多态性。
    • @DavidBrown:也许在学术意义上,但标准很清楚“多态性”在 C++ 中的含义:10.3 虚拟函数 1/虚拟函数支持动态绑定和面向对象编程。声明或继承虚函数的类称为多态类。
    • 继承虚函数的类多态类。标准是否还暗示重载/模板不是多态的?
    • @MooingDuck:标准并没有说重载和模板多态的。因此它们不符合标准,就像std::vector 不是 STL 的一部分一样。
    • 所以也许有“多态类”,但术语“多态”不限于此。 §20.8.11 中还有 多态函数包装器
    【解决方案3】:

    答案是。你可以超载它!

    #include<iostream>
    using namespace std;
    
    class Test
    {
    protected:
        int x;
    public:
        Test (int i):x(i) { }
        void fun() const
        {
            cout << "fun() const called " << endl;
        }
        void fun()
        {
            cout << "fun() called " << endl;
        }
    };
    
    int main()
    {
        Test t1 (10);
        const Test t2 (20);
        t1.fun();
        t2.fun();
        return 0;
    }
    

    输出:上述程序编译运行良好,输出如下。

    fun() called
    fun() const called
    

    “void fun() const”和“void fun()”这两个方法具有相同的签名,只是一个是 const 另一个不是。此外,如果我们仔细查看输出,我们会发现,在 const 对象上调用了“const void fun()”,在非常量对象上调用了“void fun()”。 C++ 允许在 const 类型的基础上重载成员方法。当函数返回引用或指针时,基于 const 类型的重载可能很有用。我们可以让一个函数为 const,返回一个 const 引用或 const 指针,另一个非 const 函数,返回非 const 引用或指针。

    【讨论】:

      【解决方案4】:

      是的,我们可以实现多态行为

      因为我们可以调用这些函数,一个(const function) 具有常量对象和 另一个(非常数函数)具有非常数对象。两个函数同名但用法不同,多态也指同名不同形式

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-06
        • 1970-01-01
        • 2012-07-28
        • 2020-09-13
        • 2011-04-12
        • 1970-01-01
        相关资源
        最近更新 更多