对于重载函数,为父实例和子实例调用专用版本 [英] For an overloaded function, calling specialized version for parent and child instances
问题描述
我早些时候问过问题但结果却是我的问题没有通过我的例子正确建模。所以这是我的实际问题:
I asked a question earlier but it turns out my problem was not properly modeled by my example. So here is my actual problem:
- 我的课程
A
和课程B
继承自A
, - 我有两个函数
foo(A&)
和foo(B&)
, - 我有一个
A *
指针,包含A
和B
的实例。 - 如何为
A
foo(A&) >和foo(B&)
用于B
的实例?约束:我可以修改A
和B
实现,但不能foo
的实施。
- I have class
A
, and classB
inheriting fromA
, - I have two functions
foo(A&)
andfoo(B&)
, - I have a list of
A*
pointers, containing instances ofA
andB
. - How do I get to call
foo(A&)
for instances ofA
andfoo(B&)
for instances ofB
? Constraints: I can modifyA
andB
implementation, but notfoo
's implementation.
见下面一个例子:
#include <iostream>
#include <list>
class A {
public:
};
class B : public A {
public:
};
void bar(A &a) { std::cout << "This is an A" << std::endl; }
void bar(B &b) { std::cout << "This is a B" << std::endl; }
int main(int argc, char **argv) {
std::list<A *> l;
l.push_back(new B());
l.push_back(new B());
for (std::list<A *>::iterator it = l.begin(); it != l.end(); ++it)
bar(**it);
}
虽然我使用带指针的容器, bar使用来自父类的对象调用
,而不是子类:
Although I am using a container with pointers, bar
is called with object from the parent class, not the child class:
# ./a.out
This is an A
This is an A
#
我原本期待
This is a B
将指针传递给 bar
(通过重写其签名)无济于事。
Passing pointers to bar
(by rewriting its signature) does not help.
向安东尼奥求助以澄清问题。
Thx to Antonio for helping clarifying the question.
推荐答案
由于在编译时解决了重载问题,您需要提供编译器有足够的信息来决定调用 bar
的正确过载。由于您希望根据对象的运行时类型动态做出决策,因此虚拟函数将提供很大的帮助:
Since overloading is resolved at compile time, you need to supply the compiler with enough information to decide on the proper overload of bar
to call. Since you wish to make that decision dynamically based on the run-time type of the object, virtual functions would be of great help:
struct A {
virtual void bar() { bar(*this); }
};
struct B : public A {
virtual void bar() { bar(*this); }
};
看起来机构相同,所以 B :: bar
可以被淘汰,但事实并非如此:虽然这些实体看起来完全一样,但由于过载的静态解决方案,它们会调用不同的 bar
s C ++:
It may seem like the bodies are identical, so B::bar
could be eliminated, but this is not true: although the bodies look exactly the same, they call different bar
s due to the static resolution of overloads in C++:
- 内部
A :: bar
*此
是A&
,因此调用第一个重载。 - 内部
B :: bar
的类型*此
是B&
,所以调用第二个重载。
- Inside
A::bar
the type of*this
isA&
, so the first overload is called. - Inside
B::bar
the type of*this
isB&
, so the second overload is called.
修改调用代码以调用成员 bar
将完成更改:
Modify the calling code to call the member bar
will complete the change:
std::list<A *> l;
l.push_back(new B());
l.push_back(new B());
for (std::list<A *>::iterator it = l.begin(); it != l.end(); ++it)
(*it)->bar();
这篇关于对于重载函数,为父实例和子实例调用专用版本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!