以NULL为参数的调用中的重载决策

时间:2012-08-12 22:05:37

标签: c++ constructor ambiguous

我有两个重载的构造函数:

Hello::Hello(std::string message)
{
}

Hello::Hello(int *number)
{
}

这些构造函数中的任何一个都可以获取内存地址。如果我做Hello hi(NULL);然后会被调用?

此外,如果您可以解释规则,因为它们涉及过载的对象。同样地,如果我有一个构造函数花了很长时间参数(Object::Object(long x))和另一个重载(Object::Object(SomeOtherObject o)),它接受一个本身有一个很长的重载的对象(SomeOtherObject::SomeOtherObject(long x)) 。然后我打电话给Object obj((long)5);,保证打电话给其中一个吗?

3 个答案:

答案 0 :(得分:2)

std::string构造函数进行加密需要额外的隐式转换,因此首选int*

对于第二种情况,则首选构造函数。为什么编译器在那里有完美的匹配时会寻找任何其他构造函数?同样,它包含一个隐式转换,这比直接long构造函数提供的完美匹配更糟糕。

答案 1 :(得分:2)

有一个构造函数与你的例子完全无关。它只是关于重载分辨率,您可以使用两个函数进行检查:

void foo(std::string s) {
}

void foo(int* n) {
}

致电foo(NULL)会致电foo(int*)NULL是 空指针常量,可以隐式转换为每个指针 类型和此上下文中的最佳转换是int*。另一个 过载需要进行两次转换,评级更差。

第二种情况非常明显:首选完美匹配。

答案 2 :(得分:1)

W.r.t。你在第二个问题中指出的问题是,可以强制重载解析以预期的方式运行。

当你有一个带有单个对象的类构造函数时,就像你的Object(SomeOtherObject o)一样,使用单词explicit标记该构造函数时,样式更好,因此编译器不会尝试进行隐式转换。例如。鉴于定义:

class A {
  A(int x);
};

class B {
  explicit B(A a);
};

尝试创建像B b(100)之类的对象将是编译错误。

另请参阅有关此主题的Google C++ Style Guide部分。