[dcl.fct.default]/10 中的明显矛盾
Apparent contradiction in [dcl.fct.default]/10
[dcl.fct.default]/10:
虚函数调用 (10.3) 使用 由静态类型确定的虚函数的声明 表示对象的指针或引用。覆盖函数 在派生类中不从 它覆盖的功能。[ 示例:
struct A { virtual void f(int a = 7); }; struct B : public A { void f(int a); }; void m() { B* pb = new B; A* pa = pb; pa->f(); // OK, calls pa->B::f(7) pb->f(); // error: wrong number of arguments for B::f() }
—结束示例 ]
除了我上面强调的声明外,该段和例子对我来说很清楚。当我读到这篇文章时,我的印象是它与段落的第一部分相矛盾,即虚函数调用使用虚函数声明中的默认参数,这些参数由表示对象的指针或引用的静态类型确定。
它们并不矛盾,因为它们指的是不同的东西。
虚函数调用 (10.3) 在虚函数的声明中使用默认参数,这些参数由表示对象的指针或引用的静态类型确定。
这意味着以下内容:
#include <iostream>
struct Base
{
virtual void foo(int x = 3) { std::cerr << x << 'n'; }
};
struct Derived : Base
{
virtual void foo(int x = 4) { std::cerr << x << 'n'; }
};
int main()
{
Derived d;
Base* ptr = &d;
ptr->foo(); // prints 3, not 4
}
(现场演示)
派生类中的重写函数不会从它重写的函数中获取默认参数。
另一方面,这意味着以下内容:
#include <iostream>
struct Base
{
virtual void foo(int x = 3) { std::cerr << x << 'n'; }
};
struct Derived : Base
{
virtual void foo(int x) { std::cerr << x << 'n'; }
};
int main()
{
Derived d;
d.foo(); // doesn't compile; missing value for x
}
(现场演示)
我的印象是它与该段的第一部分相矛盾,即虚函数调用使用虚函数声明中的默认参数,该参数由表示对象的指针或引用的静态类型确定。
不。这意味着,如果你通过它的 Base 接口访问对象,你将获得 Base 的默认参数......如果你通过它的 Derived 接口访问对象,并且 Derived 没有自己的默认参数,你将不会得到 Base 的参数。同一枚硬币的两个截然不同的方面。
而且,公平地说,引用的标准文本给出了完全相同的例子。
这意味着派生类中的函数可以有自己的默认参数,也可以没有默认参数。
例如
struct A {
virtual void f(int a = 7)
{
std::cout << "F(" << a << ")" << std::endl;
}
};
struct B : public A {
void f(int a = 10)
{
std::cout << "F(" << a << ")" << std::endl;
}
};
B* pb = new B;
A* pa = pb;
pa->f(); // OK, calls pa->B::f(7)
pb->f(); // OK, calls pa->B::f(10)
在第一次调用中
pa->f(); // OK, calls pa->B::f(7)
根据指针的静态类型,使用了函数 f 声明的默认参数pa
即函数在类 A 中的声明。
在第二个调用中
pb->f(); // OK, calls pa->B::f(10)
根据指针pb
的静态类型,使用函数 F 声明的默认参数,即类 B 中函数的声明。
相关文章:
- 矛盾的未解决的外部符号+未使用的库与VS2017和FFMPEG 4
- C++指向连续矢量元素的指针是矛盾的
- 这是当前草案中[Expr.Ref]/(4.2)和[Expr.sub]/1之间的矛盾
- [dcl.fct.default]/10 中的明显矛盾
- 将枚举类型保存在位字段 [dcl.enum] [class.bit] 中
- 特征张量的问题:声明矛盾
- [lex.ccon] 中 c-char 的定义可能存在矛盾
- 如[dcl.typedef]/9所述,仅针对"linkage purposes"的链接声明的目的是什么?
- 在CentOS 7 x64上编译QT时,如何解决矛盾的库问题
- C++11: "auto"关键字会检索到cv限定符吗?我有矛盾的样本
- 是numeric_limits&lt; int&gt; :: is_modulo从逻辑上矛盾
- 对 c++1z 中的 [dcl.spec]/3 的疑问
- 矛盾的错误消息 - 运算符重载<<
- 等效static_asserts为is_array<>提供相互矛盾的结果
- 逻辑矛盾是否在类设计中背叛了OOP
- 将shared_ptr的嵌套智能指针重置为shared_ptr(或unique_ptr),看起来很矛盾
- 模板类中的尾随返回类型(GNU和Microsoft编译器之间的矛盾)
- 关于“auto_ptr”模板类,这两个来源之间是否存在矛盾
- C++函数的执行时间矛盾
- 该"Named Constructor Idiom"似乎与静态方法无法访问非静态成员函数的规则相矛盾。有什么解释吗?