class 中未调用虚函数
Virtual function not called in class
在下面的 main()
函数中,d
是一个基 class 指针(A
类型),它指向派生的 class(属于输入 B
)。然而,当成员函数 f(int)
在此指针上调用时,即 d->f(1)
,编译器调用基 class A 中的非虚函数(标记为 #2
),即
void f(int n) const { std::cout << n; }
为什么?我期待,因为在基础 class A
中也有一个虚函数
virtual void f(int n) { std::cout << n; }
派生的 class B
中的两个函数 f(int)
之一将被调用。我哪里错了?
class A
{
public:
A() {}
public:
virtual void f(int n) { std::cout << n; } // #1
virtual ~A() { }
void f(int n) const { std::cout << n; } // #2 this function is called when d->f(1) is executed in main()
};
class B
: public A
{
public:
void f(int n) { std::cout << n; } // #3
void f(int n) const { std::cout << n; } // #4
};
int main()
{
B b;
const A* d = &b;
d->f(1); // this calls function #2 above - why?
std::cout << std::endl;
return 0;
}
d
是指向 const A
的指针。这意味着对成员函数的任何调用都将调用 const 限定的重载(如果存在的话)。在你的例子中,基础 class (#2
) 中 f
的 const 限定版本不是 virtual
,所以 d
指向的事实B
对象无关紧要。基础 class const 限定的重载是被选择调用的重载。
如果在基础 class virtual
中进行 f
的 const 限定重载,则派生 class 中的 const 限定重载(#4
) 将被选中。
类似地,如果 d
是指向非常量 A
的指针,则派生的 class 中 f
的非常量限定重载( #3
) 将被调用,因为基 class (#1
) 中的重载是 virtual
.
在下面的 main()
函数中,d
是一个基 class 指针(A
类型),它指向派生的 class(属于输入 B
)。然而,当成员函数 f(int)
在此指针上调用时,即 d->f(1)
,编译器调用基 class A 中的非虚函数(标记为 #2
),即
void f(int n) const { std::cout << n; }
为什么?我期待,因为在基础 class A
virtual void f(int n) { std::cout << n; }
派生的 class B
中的两个函数 f(int)
之一将被调用。我哪里错了?
class A
{
public:
A() {}
public:
virtual void f(int n) { std::cout << n; } // #1
virtual ~A() { }
void f(int n) const { std::cout << n; } // #2 this function is called when d->f(1) is executed in main()
};
class B
: public A
{
public:
void f(int n) { std::cout << n; } // #3
void f(int n) const { std::cout << n; } // #4
};
int main()
{
B b;
const A* d = &b;
d->f(1); // this calls function #2 above - why?
std::cout << std::endl;
return 0;
}
d
是指向 const A
的指针。这意味着对成员函数的任何调用都将调用 const 限定的重载(如果存在的话)。在你的例子中,基础 class (#2
) 中 f
的 const 限定版本不是 virtual
,所以 d
指向的事实B
对象无关紧要。基础 class const 限定的重载是被选择调用的重载。
如果在基础 class virtual
中进行 f
的 const 限定重载,则派生 class 中的 const 限定重载(#4
) 将被选中。
类似地,如果 d
是指向非常量 A
的指针,则派生的 class 中 f
的非常量限定重载( #3
) 将被调用,因为基 class (#1
) 中的重载是 virtual
.