C++ 强制转换何时调用新类型的构造函数?
确定特定静态类型转换是否调用类的构造函数的规则是什么?c样式/函数样式转换如何?如果有合适的转换构造函数,则转换构造函数将由C++ 强制转换何时调用新类型的构造函数?,c++,casting,C++,Casting,确定特定静态类型转换是否调用类的构造函数的规则是什么?c样式/函数样式转换如何?如果有合适的转换构造函数,则转换构造函数将由静态\u转换调用: class Class { public: Class( int ); //<< conversion constructor }; int what = 0; Class object = static_cast<Class>( what ); 每当创建一个类类型的新实例时,就会调用该类类型的构造函数。如果强制转换创
静态\u转换调用:
class Class {
public:
Class( int ); //<< conversion constructor
};
int what = 0;
Class object = static_cast<Class>( what );
每当创建一个类类型的新实例时,就会调用该类类型的构造函数。如果强制转换创建该类类型的新对象,则调用构造函数。重载解析确定在给定特定参数的情况下调用类类型的哪些构造函数
如果静态_cast
的目标类型是类类型,它将创建目标类型的新对象
const\u cast
、dynamic\u cast
或reinterpret\u cast
永远不会创建新的类类型对象,因此永远不会调用构造函数
由于C样式转换总是执行static\u cast
、const\u cast
和reinterpret\u cast
的组合,因此它将在与static\u cast
创建新对象相同的情况下创建新对象。每当创建新对象时,都会调用构造函数。static\u cast
总是会产生一个新的临时对象(但请参见James McNellis的评论)
立即,或通过调用用户定义的转换。(但在
为了返回所需类型的对象,用户定义
转换运算符必须调用构造函数。)
当目标是类类型时,C样式强制转换和函数样式强制转换
根据定义,具有单个参数的强制转换与
static\u cast
。如果功能样式转换有零个或多个
参数,则它将立即调用构造函数;用户定义
在这种情况下不考虑转换运算符。(人们可以
质疑是否选择将其称为“类型转换”。)
对于记录,用户定义的转换运算符可能是
称为:
A类
{
int m_值;
平民的
A(int initialValue):m_值(initialValue){}
};
B类
{
int m_值;
公众:
B(int initialValue):m_值(initialValue){}
运算符A()常量{返回一个(m_值);}
};
无效f(常数和参数);
B someB;
f(静态_-cast(arg));
在这种特殊情况下,不需要强制转换,转换
将在其缺席的情况下进行隐式修改。但在所有情况下:都是隐性的
转换、静态转换、C样式转换((A)someB
)或功能转换
样式转换(A(someB)
),
B::操作符A()
将被调用。)如果构造函数是显式的,该怎么办?我假设它仍然会被调用。@Mankarse:是的,explicit
意味着没有指定类型就不能调用它。当您指定类型时,它将被调用。这是正确的,但重要的是要说明它何时创建新实例(IIRC函数样式转换总是这样做,当超过cv限定时,静态转换也会这样做)。当目标类型为类类型时,创建新类类型对象的唯一时间是通过static\u cast
。注意,如果源类型有一个到目标类型的转换运算符,那么静态强制转换本身可能不会调用构造函数,但是“调用了构造函数”。转换操作符很可能调用一个,再加上考虑返回值的一个潜在的复制副本结构。只有在转换运算符直接或间接调用某个ctor的情况下,才能省略该副本。“静态转换总是生成新的临时对象”不是真的。例如,给定类层次结构structb{};结构D:B{}
,以下静态\u cast
不会创建新对象:D;B&B(静态铸造(d))代码>。任何目标类型为对象类型的static\u cast
都将创建一个新对象。@James是的,我应该更精确一些。我在考虑类类型(因为问题涉及到构造函数);事实上,规则很简单(对于所有类型转换也是如此):如果结果是引用,则没有新对象;否则,就没有了。(就标准而言,类型转换的结果是左值,当且仅当转换为引用类型时。)有趣的是,它不会在c数据类型的情况下创建副本@JamesMcNellis你所说的对象类型是什么意思?如果我有两个具有公共基的派生类,例如:struct A{};结构D1:A{};结构D2:A{D2(常数A&)};然后是D1和D1;静态_cast(d1)调用ctor
int what = 0;
Class object = (Class)what;
int what = 0;
Class object = Class( what );
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 ) );