C ++:显式构造函数由派生类隐式调用

时间:2014-06-17 19:42:16

标签: c++

为什么使构造函数显式化并不会阻止派生类隐式调用它?

class A{
public:
    explicit A(){}
};

class B : public A{
public:
    B(){ //Constructor A() is called implicitly

        //...
    }
}

我的程序中有一种情况,当我在这种情况下宁愿遇到编译错误时,它会省去很多时间来查找错误。现在我改变了A的默认构造函数来接受一个虚拟的“int”参数来实现它,但不应该“显式”关键字为此工作吗?

g ++ - 4.8编译上面的代码,没有任何错误或警告。

2 个答案:

答案 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;
}