【发布时间】:2011-06-07 05:36:24
【问题描述】:
确定特定的 static_cast 是否会调用类的构造函数的规则是什么? c 风格/函数式风格转换怎么样?
【问题讨论】:
确定特定的 static_cast 是否会调用类的构造函数的规则是什么? c 风格/函数式风格转换怎么样?
【问题讨论】:
每当创建一个新对象时,都会调用一个构造函数。 static_cast 总是会产生一个新的临时对象(但请参阅 James McNellis 的评论)
立即,或通过调用用户定义的转换。 (但在
为了返回所需类型的对象,用户定义
转换运算符必须调用构造函数。)
当目标是类类型时,C风格转换和函数风格
根据定义,带有单个参数的强制转换与 a
static_cast。如果函数式风格转换有零个或多个
参数,那么它会立即调用构造函数;用户自定义
在这种情况下不考虑转换运算符。 (而且可以
质疑将其称为“类型转换”的选择。)
作为记录,用户定义的转换运算符可能是 叫:
class A
{
int m_value;
public
A( int initialValue ) : m_value( initialValue ) {}
};
class B
{
int m_value;
public:
B( int initialValue ) : m_value( initialValue ) {}
operator A() const { return A( m_value ); }
};
void f( A const& arg );
B someB;
f( static_cast<A>( arg ) );
在这种特殊情况下,强制转换是不必要的,并且转换
将在其缺席时隐式生成。但在所有情况下:隐式
转换、static_cast、C 风格转换 ((A) someB) 或函数式
风格演员(A( someB )),
B::operator A() 将被调用。)
【讨论】:
static_cast 总是产生一个新的临时对象”不正确。例如,给定类层次结构struct B { }; struct D : B { };,以下static_cast 不会创建新对象:D d; B& b(static_cast<B&>(d));。目标类型为对象类型的任何static_cast 都将创建一个新对象。
每当创建该类型的新实例时,都会调用该类类型的构造函数。如果强制转换创建了该类类型的新对象,则调用构造函数。重载决议确定在给定特定参数的情况下调用类类型的哪些构造函数。
如果static_cast的目标类型是类类型,它将创建一个目标类型的新对象。
const_cast、dynamic_cast 或 reinterpret_cast 永远不会创建新的类类型对象,因此永远不会调用构造函数。
由于 C 风格的转换总是执行 static_cast、const_cast 和 reinterpret_cast 的某种组合,因此它会在 static_cast 创建新对象的相同情况下创建一个新对象。
【讨论】:
static_cast。我已经用这个细节更新了答案。
如果有合适的转换构造函数,该转换构造函数将被static_cast调用:
class Class {
public:
Class( int ); //<< conversion constructor
};
int what = 0;
Class object = static_cast<Class>( what );
这同样适用于 C 风格的转换和“函数式”转换。
int what = 0;
Class object = (Class)what;
int what = 0;
Class object = Class( what );
【讨论】:
explicit 表示如果不指定类型就无法调用它。当您指定类型时,它将被调用。