2010-03-15 74 views
3

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

我的意思是,它会通过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"; 
} 
+0

我想这篇文章可能是一个很好的用例,为什么明确的关键字存在。 – sivabudh 2010-03-15 23:44:44

+0

我应该将副本构造函数的标题重命名为转换器构造函数吗? – sivabudh 2010-03-15 23:53:03

回答

3

因为您提供了一个转换构造函数。如果你不希望编译器使用

Child(Base const& base_) 

构造Base对象自动转换为Child,使其明确:

explicit Child(Base const& base_) 

这种方式,构造函数才会被调用时,您明确指定它,像背景:

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

谢谢。现在我明白了明确的关键字的需求。 – sivabudh 2010-03-15 23:42:27

0

因为你不提供任何操作=()以基本作为参数:编译器将尝试“W帽子他可以“,并且看到有一个可以调用的参数类型(Child)的转换构造函数。所以它使用它来使!=工作。

1

因为儿童不能与基地相比 - 它只能与另一个孩子比较。因此,您的编译器会创建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; 
    } 
}; 

您会发现它不再编译。

6

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

相关问题