协变虚函数的 C++ 规则
C++ rules for covariant virtual function
我正在阅读 Covariant virtual function。它说
假设B::f覆盖了虚函数A::f。如果满足以下所有条件,A::f 和 B::f 的 return 类型可能会有所不同:
1) The const or volatile qualification of the pointer or reference
returned by B::f has the same or less const or volatile qualification
of the pointer or reference returned by A::f.
2) A::f returns an lvalue reference if and only if B::f returns an
lvalue reference.
3) The function B::f returns a pointer or a reference to a class of
type T, and A::f returns a pointer or a reference to an unambiguous
direct or indirect base class of T.
4) The return type of B::f must be complete at the point of declaration of B::f, or it can be of type 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;
}
如果我错了请指正somewhere.I 对前 2 条规则感到困惑。
谢谢
非常感谢您的帮助。
第一条规则意味着如果 A
版本,您不能将覆盖函数 return 设为具有 const
或 volatile
的 B
没有:
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*
第二条规则意味着您不能将不同的引用或指针类型作为协变 return 类型。使用与上面相同的示例:
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
您的示例满足这两个规则,因为两个 return 类型具有相同的 cv 限定并且都是左值引用。
我正在阅读 Covariant virtual function。它说
假设B::f覆盖了虚函数A::f。如果满足以下所有条件,A::f 和 B::f 的 return 类型可能会有所不同:
1) The const or volatile qualification of the pointer or reference returned by B::f has the same or less const or volatile qualification of the pointer or reference returned by A::f.
2) A::f returns an lvalue reference if and only if B::f returns an lvalue reference.
3) The function B::f returns a pointer or a reference to a class of type T, and A::f returns a pointer or a reference to an unambiguous direct or indirect base class of T.
4) The return type of B::f must be complete at the point of declaration of B::f, or it can be of type 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;
}
如果我错了请指正somewhere.I 对前 2 条规则感到困惑。
谢谢
非常感谢您的帮助。
第一条规则意味着如果 A
版本,您不能将覆盖函数 return 设为具有 const
或 volatile
的 B
没有:
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*
第二条规则意味着您不能将不同的引用或指针类型作为协变 return 类型。使用与上面相同的示例:
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
您的示例满足这两个规则,因为两个 return 类型具有相同的 cv 限定并且都是左值引用。