0

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

我担心,由于可以将任何指针转换为void*,下面的第二次调用 bar 会在下面的程序中执行void bar(void*)而不是我的预期void bar(int*)吗?

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

富.h:

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* 参数作为第一种形式,将基抽象类指针参数作为第二种形式。以派生类指针作为参数的调用会执行第一种形式还是第二种形式?即派生类指针会被转换为它的基抽象类指针(因此第二种形式将起作用),还是void *在调用之前将其转换为(因此第一种形式将起作用)bar()

4

1 回答 1

4

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

为了:

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 ( Conversion ),因此这遵循转换排名规则。由于两个转化具有相同的转化排名,因此这将进入扩展的转化排名规则。扩展规则 2 规定:

将派生指针转换为基址指针优于派生指针转换为void指针,基址指针转换为void优于派生指针作废。

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

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

于 2016-07-04T18:41:05.243 回答