为什么使构造函数显式化并不会阻止派生类隐式调用它?
class A{
public:
explicit A(){}
};
class B : public A{
public:
B(){ //Constructor A() is called implicitly
//...
}
}
我的程序中有一种情况,当我在这种情况下宁愿遇到编译错误时,它会省去很多时间来查找错误。现在我改变了A的默认构造函数来接受一个虚拟的“int”参数来实现它,但不应该“显式”关键字为此工作吗?
g ++ - 4.8编译上面的代码,没有任何错误或警告。
答案 0 :(得分:8)
您对explicit
关键字的假设是错误的。
explicit
关键字并不是要阻止构造函数从派生类调用,而是以防止隐式转换,就像在这里示例:https://stackoverflow.com/a/121163/1938163
我在这里总结相关部分:
class Foo
{
public:
// single parameter constructor, can be used as an implicit conversion
Foo (int foo) : m_foo (foo)
{
}
int GetFoo () { return m_foo; }
private:
int m_foo;
};
由于最多可以进行一次隐式转换来解决歧义,如果你有一个像
这样的函数void DoBar (Foo foo)
{
int i = foo.GetFoo();
}
以下是合法的:
int main ()
{
DoBar (42); // Implicit conversion
}
这正是显式关键字发挥作用的地方:禁止上述情况。
要解决您的问题,为了防止您的类被用作基类,只需使用 final 标记构造函数,如果您使用的是C ++ 11(http://en.wikipedia.org/wiki/C++11#Explicit_overrides_and_final )
答案 1 :(得分:1)
显式关键字通常用于具有一个参数的构造函数。它可以防止对象的隐式构造从参数类型到类的类型。
以下示例将进行编译,通常不是您想要的:
#include <iostream>
using namespace std;
struct Test
{
Test(int t) {}
};
void test_fun(Test t) {}
int main() {
test_fun(1); //implicit conversion
return 0;
}
使用显式关键字,此示例不会编译:
#include <iostream>
using namespace std;
struct Test
{
explicit Test(int t) {}
};
void test_fun(Test t) {}
int main() {
test_fun(1); //no implicit conversion, compiler error
return 0;
}