协变虚函数的C ++规则

时间:2015-05-08 14:38:33

标签: c++ c++11 virtual-functions

我正在阅读Covariant virtual function。它说

假设B :: f覆盖虚函数A :: f。如果满足以下所有条件,则A :: f和B :: f的返回类型可能不同:

  

1)指针或引用的const或volatile限定   由B :: f返回的具有相同或更少的const或volatile限定条件   A :: f返回的指针或引用。

     

2)当且仅当B :: f返回时,A :: f才返回左值引用   左值参考。

     

3)函数B :: f返回指针或对类的引用   输入T,A :: f返回指针或对明确的引用   直接或间接的基类T.

     

4)B :: f的返回类型必须在声明B :: f时完成,或者它可以是B类型

有人会举一个适当的例子来解释上述两条规则吗?这两条规则究竟是什么意思?第二条规则适用于C ++ 11吗? 以下示例是否满足我在此处说过的第一条规则?

#include <iostream>
class Base {
    public:
        virtual const Base& fun() const
        {
            std::cout<<"fun() in Base\n";
            return *this;
        }
        virtual ~Base()
        { }
    private:
        int a=3;
};
class Derived : public Base
{
        const Derived& fun() const
        {
            std::cout<<"fun() in Derived\n";
            return *this;
        }
};
int main(){
    Base* p=new Derived();
    p->fun();
    delete p;
    return 0;
}

请纠正我如果我在某处错了。我在前2条规则中感到困惑。

由于

我们非常感谢您的帮助。

1 个答案:

答案 0 :(得分:4)

如果B版本没有,则第一条规则意味着您无法使覆盖的函数返回const volatileA <\ n} { / p>

struct A
{
    virtual A* foo() { return new A{}; }    
};

struct B : A
{
    B* foo() override {return new B{}; }          //valid
    const B* foo() override {return new B{}; }    //invalid
    volatile B* foo() override {return new B{}; } //invalid
};

如果考虑调用网站,这是有道理的:

A* my_b = new B{};
A* new_b = my_b->foo(); //discards the const qualifier if B::foo() returns const B*

第二条规则意味着您不能将不同的引用或指针类型作为协变返回类型。使用与上面相同的例子:

struct A
{
    virtual A* foo() { return new A{}; }    
};

struct B : A
{
    B* foo() override {return new B{}; }   //valid
    B& foo() override {return new B{}; }   //invalid
    B&& foo() override {return new B{}; }  //invalid
};

再次考虑一下呼叫网站:

A* my_b = new B{};
A* new_b = my_b->foo(); //if B::foo() returns a reference, this line is syntactically ill-formed

您的示例满足两个规则,因为两个返回类型具有相同的cv限定,并且都是左值引用。