对于重载函数,为父实例和子实例调用专用版本 [英] For an overloaded function, calling specialized version for parent and child instances

查看:204
本文介绍了对于重载函数,为父实例和子实例调用专用版本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我早些时候问过问题但结果却是我的问题没有通过我的例子正确建模。所以这是我的实际问题:

I asked a question earlier but it turns out my problem was not properly modeled by my example. So here is my actual problem:


  1. 我的课程 A 和课程 B 继承自 A

  2. 我有两个函数 foo(A&) foo(B&)

  3. 我有一个 A * 指针,包含 A B 的实例。

  4. 如何为 A foo(A&) >和 foo(B&)用于 B 的实例?约束:我可以修改 A B 实现,但不能 foo 的实施。

  1. I have class A, and class B inheriting from A,
  2. I have two functions foo(A&) and foo(B&),
  3. I have a list of A* pointers, containing instances of A and B.
  4. How do I get to call foo(A&) for instances of A and foo(B&) for instances of B? Constraints: I can modify A and B implementation, but not foo'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 bars due to the static resolution of overloads in C++:


  • 内部 A :: bar *此是 A& ,因此调用第一个重载。

  • 内部 B :: bar 的类型*此 B& ,所以调用第二个重载。

  • Inside A::bar the type of *this is A&, so the first overload is called.
  • Inside B::bar the type of *this is B&, 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆