我不确定这里使用的术语是什么,这使得查找有关它的信息变得困难。之后我的代码感到惊讶(点击编译,意识到我忘了更新几个地方......无论如何编译并且没有错误地运行),我做了一个简单的例子来验证它。
我有一个包含另一个类的容器类。它有一个构造函数,它对它包含的类进行const引用。我有另一个函数,它接受容器类的const引用。我可以传递函数一个包含类的实例,它会自动为我创建一个容器类的临时表。没有警告(-Wall -pedantic -Wextra -Werror
)。
#include <iostream>
class A { // Contained class.
public:
A(int i) : a_number_(i) {}
void print() const { std::cout << a_number_ << "\n"; }
private:
int a_number_;
};
class A_Container { // Container class.
public:
~A_Container() { delete a_; }
A_Container(const A& a) : a_(new A(a)) { std::cout << "I was called!\n"; }
const A& getA() const { return *a_; }
private:
A* a_;
};
void foo(const A_Container& container) { // This func takes a container...
container.getA().print();
}
int main() {
A a(147);
foo(a); // ...but I'm passing it the contained class.
return 0;
}
输出:
I was called!
147
这叫什么?这种转换有哪些要求?
我可以看到它使有意义让它起作用,但它还有比编译器魔法更多的东西吗?
编辑:
答案 0 :(得分:2)
如果C ++有一个没有标记为explicit
的单参数构造函数,它将隐式为您构造容器类。为了避免偶然发生这种情况,通常将一元构造函数限定为显式:
explicit Container(const A& a);
现在它不会编译(在某些情况下是一种改进,以避免意外地&#34;工作&#34;代码,如果它实际上是错误的或不合需要的。)