繁体   English   中英

C ++为什么隐式调用转换器构造函数?

[英]C++ Why is the converter constructor implicitly called?

为什么在下面的代码中调用了Child类的转换器构造函数?

我的意思是,它通过子转换器构造函数自动将Base转换为Child。 下面的代码编译,但应该不会,因为我还没有提供它无法编译bool Child::operator!=(Base const&)

class Base
{
};

class Child : public Base
{
public:
  Child() {}
  Child(Base const& base_) :
    Base(base_)
  {
    std::cout <<"should never called!";
  }
  bool operator!=(Child const&)
  {
    return true;
  }
};

void main()
{
  Base  base;
  Child child;

  if(child != base)
    std::cout << "not equal";
  else
    std::cout << "equal";
}

具有签名Child(Base const& base_)函数不是复制构造函数(右侧类型与左侧不同)。 编译器可以隐式使用该构造函数将一种类型强制转换为另一种类型,以便在main中进行比较。 为了防止这个标记,构造函数是explicit

因为您提供了转换构造函数。 如果您不希望编译器使用自动将Base对象转换为Child

Child(Base const& base_)

构造函数,使其明确:

explicit Child(Base const& base_)

这样,只有在您明确指定构造函数时,才会调用构造函数,例如:

Child ch(base);
foo(Child(base));
new Child(base);

因为Child无法与Base比较 - 它只能与另一个Child进行比较。 因此,您的编译器会创建Base to Child的隐式副本以进行转换。 如果您将代码更改为:

class Child : public Base
{
public:
  Child() {}
  explicit Child(Base const& base_) :
    Base(base_)
  {
    std::cout <<"should never called!";
  }
  bool operator!=(Child const&)
  {
    return true;
  }
};

你会发现它不再编译。

因为你没有提供任何以Base作为参数的运算符!=():编译器将尝试“他能做什么”并且看到有一个可以被调用的参数类型(Child)的转换构造函数。 所以用它来做!=工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM