《C++ Primer》(英文版,第4版) p. 461提到:
A constructor that can be called with a single argument defines an implicit conversion from the parameter type to the class type.
(如果一个类的构造函数只接收一个实参(argument),那么就定义了一个从形参(parameter)数据类型到类的类型的隐式转换。)
参考下面的例子,并且注意后面的注释。
#include <iostream>
#include <string>
using namespace std;
class Book
{
public:
// 如果一个类的构造函数只接收一个实参(argument),那么就定义了一个从形参(parameter)数据类型到类的类型的隐式转换。
// 因此,在下面的构造函数,可隐式地将string类型转换成Book类型
Book(const string& book_name) : author("Stanley B. Lippman")
{
this->book_name = book_name;
}
// same_author的形参是const Book&
bool same_author(const Book& book) const;
private:
string book_name;
string author;
};
bool Book::same_author(const Book& book) const
{
return (this->author == book.author);
}
int main(void)
{
// 定义了一本书Inside C++ Object Model,其作者是缺省的
Book a_book("Inside C++ Object Model");
// 定义一个字符串,作为一本书的书名
string b_book_name("C++ Primer");
// 下面这种调用方式将会产生编译错误:不能将参数1 从“const char [11]”转换为“const Book &”
//if(a_book.same_author("C++ Primer"))
// 按照常理,if中的same_author的参数应该是Book类型,
// 但在这里,我们传入了一个string类型的实参b_book_name,
// 它将会隐式调用Book类的对应的构造函数,并将其换成一个
// 临时的Book对象,这样便满足了same_author的参数要求
if(a_book.same_author(b_book_name))
{
cout << "The great 2 books are written by great Stanley B. Lippman" << endl;
}
else
{
cout << "Different authors for those 2 books." << endl;
}
return 0;
}
下面说说explicit这个关键字的作用。
如果把上面程序中Book类的构造函数:
Book(const string& book_name) : author("Stanley B. Lippman")
改成:
explicit Book(const string& book_name) : author("Stanley B. Lippman")
那么原来的程序将会出现编译错误:
“Book::same_author”: 不能将参数1 从“std::string”转换为“const Book &”
explicit关键字,将会阻止原来的隐式转换。这时如果把
if(a_book.same_author(b_book_name))
改成
Book b_book(b_book_name);
if(a_book.same_author(b_book))
就可以了。