问题描述
你能解释一下 static_cast 的工作吗?
为什么此代码不起作用?
D another_d = static_cast<D>(br); // ERROR - no matching function for call to ‘D::D(B&)’
我的代码
#include <bits/stdc++.h>
using namespace std;
struct B {
int m = 0;
void hello() const {
std::cout << "Hello world,this is B!\n";
}
};
struct D : B {
void hello() const {
std::cout << "Hello world,this is D!\n";
}
};
int main(){
D d;
B br = d; // upcast via implicit conversion
br.hello(); // Hello world,this is B!
// D another_d = static_cast<D>(br); // ERROR - no matching function for call to ‘D::D(B&)’
D& another_d = static_cast<D&>(br); // OK
another_d.hello(); // Hello world,this is D!
}
解决方法
B br = d; // upcast via implicit conversion
这是object slicing。 br
是 B
的实例,仅复制 B
的 d
部分。 (这意味着将 d
向下转换为 B&
,编译器可以隐式执行此操作,因为 D
派生自 B
。)
D another_d = static_cast<D>(br);
这是尝试从 D
的实例创建 B
的实例。
虽然 D
也是 B
(由于继承),但事实并非如此。
因此,编译器无法隐式执行任何操作。
要使其正常工作,必须定义一个构造函数 D(B&)
。
为了说明这一点:D
可能具有无法从 B
复制的其他成员变量,这就是此类构造函数必须以任何方式处理的内容。
D& another_d = static_cast<D&>(br); // OK
这不太好。它可能(似乎)工作,因为 D
不包含额外的成员变量。
br
是 B
的实例(不是 D
的实例)。 “伪造”对 D
的引用实际上是一个谎言,但明确地(在代码中)这样做会使编译器保持沉默。然而,它仍然是错误的。