想象一下以下场景
public sealed class FixedWidth96Converter : ConverterBase
{
public override string FieldToString(object from)
{
string val = from as string;
if (!string.IsNullOrWhiteSpace(val))
{
return val.PadLeft(96, ' ');
}
return base.FieldToString(from);
}
public override object StringToField(string from)
{
return from;
}
}
输出非常明确:2和2由于虚拟和向下转换(从基础到孩子)。
但是,在代码中进行一些更改,如:
class B
{
public:
int n;
B() { n = 1;};
virtual int shift() const { return n; }
};
class D : public B
{
public:
D() { n = 2;};
int shift() const { return n; }
};
int main()
{
D d;
std::cout << d.shift() << std::endl;
B *b = &d;
std::cout << b->shift() << std::endl;
std::cin.get();
return 0;
}
并保持相同的main(),我们的输出将是:2和1.为什么&#34; 1&#34;如果方法是虚拟的?
非常感谢!
答案 0 :(得分:0)
在本声明中
std::cout << b->shift() << std::endl;
编译器根据指针B
的静态类型使用类b
中函数的声明,并使用相应的默认参数。
首先,编译器会计算函数的参数,而这个参数是声明
的默认参数virtual int shift(int n = 1) const { return n; }
然后使用动态绑定并调用类D
中的函数。:)
尝试以下示例
#include <iostream>
int main()
{
struct B
{
virtual ~B() = default;
virtual int shift(int n = 1) const { std::cout << "B::shift( int ): "; return n; }
};
struct D : B
{
virtual int shift(int n = 2) const { std::cout << "D::shift( int ) : "; return n; }
};
D d;
B *b = &d;
std::cout << b->shift() << std::endl;
}
你会得到
D::shift( int ) : 1
^^^ ^^^
即编译器根据指针shift
的静态类型搜索类B
范围内的名称b
。但是使用动态绑定机制从类D
调用函数。
答案 1 :(得分:-1)
显然,编译器在函数名称的修改中使用默认参数值。
上述评论中的副本提供了另一个原因。编译器在编译时解析默认参数。