C++ 多态函数以 void * 和其他指针类型为参数:是否被认为是模棱两可的



C++多态函数以void *和其他指针类型为参数:它被认为是模棱两可的吗?

我担心由于任何指针都可以投射到void*,下面的第二个柱线调用是否会在下面的程序中执行void bar(void*)而不是我预期的void bar(int*)

我在 g++ 上进行了测试,它按预期运行(即 int* 不会被转换为 void*(。 但是,任何人都可以在C++语言规范方面评论/回答/回答这个问题吗?

傅炯:

class Foo {
public:
    void bar(void *);
    void bar(int *);
};

主.cpp:

...
struct A *p1;
int *p2;
Foo foo;
...
foo.bar(p1);
foo.bar(p2);

此外,比如说,bar现在是虚拟多态函数,将void*参数作为第一种形式,将基本抽象类指针参数作为第二种形式。 使用派生类指针作为参数的调用是执行第 1 种形式还是第 2 种形式?即派生类指针是被强制转换为其基本抽象类指针(因此第二个形式将起作用(,还是在调用bar()之前将其转换为void *(因此第一个形式将起作用(?

根据重载解析规则(隐式转换序列的排名部分(,由于参数可以转换为任一函数的参数类型,在这种情况下,最可行的函数将是隐式转换更好的函数。

为:

class Foo {
  public:
    void bar(void*);
    void bar(int*);
};
// ...
Foo foo;
int* p2;
foo.bar(p2);

第一个是等级 3(转换(,而第二个是等级 1(完全匹配(。 由于不需要转换的完全匹配比转换更好,因此它将调用void bar(int*)

但是,在第二种情况下,它会变得更加复杂:

class Foo {
  public:
    virtual void bar(void*);
    virtual void bar(Foo*);
    virtual ~Foo() = default;
};
class FooTwo : public Foo {};
// ...
Foo foo;
FooTwo footwo;
foo.bar(&footwo);

由于两者都是排名 3(转换(,因此遵循转换排名规则。 由于两次转化具有相同的转化排名,因此这将转到扩展的转化排名规则。 扩展规则 2 规定:

将指针到派生转换为指针到基的转换比将指针到派生转换为指针到

空要好,并且将指针到基数转换为 void 比将指针到派生转换为 void 更好。

考虑到这一点,void bar(Foo*)被认为是比void bar(void*)更好的匹配,这意味着它将被foo.bar(&footwo);选择。

有关后者的示例,请参阅此处。

最新更新