为什么我无法将指向派生类的指针转换为引用指向基类的指针?
struct Base { };
struct Derived : Base { };
int main()
{
Derived* derived = nullptr;
static_cast<Base*&>(derived);
}
我得到:
invalid static_cast from type 'Derived*' to type 'Base*&'
根据您的评论:
“不,这不是一个学术问题。我需要调用一个以参数为参数的函数
Base*&
”
解决此问题的正确方法是创建一个适当类型的新指针变量,并将其(或者更确切地说,对其的引用)传递给相关函数:
struct Base { };
struct Derived : Base { };
int main()
{
Derived* derived = nullptr;
Base* base = static_cast<Base*>(derived);
my_function(base); // takes a Base*& argument
// If you need the pointer value and are sure that
// it's a Derived* type:
derived = static_cast<Derived*>(base);
}
请注意,如果您在问题本身中包含相关信息(来自我上面引用的评论),您可能会更快收到此答案。
因为
Derived*
对象不是 Base*
对象,并且两者完全有可能具有不同的内存布局或值表示(例如,如果 Base
和 Derived
的对齐要求不同)。由于一个不是另一个,static_cast
无法执行转换。
如果您知道自己在做什么并且知道类型双关语没问题,请使用类型双关语工具 —
reinterpret_cast
:
reinterpret_cast<Base*&>(derived);
并注意误用的任何后果(与往常一样
reinterpret_cast
)。特别注意,根据 C++11 3.10/10,就标准而言,通过转换结果进行的任何访问都将是未定义行为(尽管您的编译器可能会提供更强的保证)。
请注意,在一般情况下,从
Derived*
到 Base*
的转换不必是无操作。例如,如果涉及多重继承,则可能涉及地址移位。
扩展https://stackoverflow.com/users/1782465/angew-is-no-longer-proud-of-so提供的答案,您可以尝试此代码来了解为什么引用 Base* (即
Base*&
) 无法绑定到 Derived*
:
struct B {
int valb;
};
struct D : B {
int vald;
};
template<typename T>
struct SC {
T vald_sc;
};
template<typename T>
struct MV {
int valmv;
T& valb;
MV(T& vb) : valb(vb) {}
};
void f1(B* dp) {
}
void f2(B*& dp) {
}
void f3(B** dp) {
}
int main() {
SC<D> sc;
MV<B> mv(sc.vald_sc); //Conversion succeeds because a D object is a B object: their memory layout starts at the same addr
SC<D*> scp;
//MV<B*> mvp(scp.vald_sc); //Error: candidate constructor not viable: no known conversion from 'D *' to 'B *&' for 1st argument
//NB: A D* object is not a B* object.
MV<B*> mvp1(reinterpret_cast<B*&>(scp.vald_sc));
MV<B*> mvp2(*reinterpret_cast<B**>(scp.vald_sc));
f1(scp.vald_sc);
f2(reinterpret_cast<B*&>(scp.vald_sc));
f2(*reinterpret_cast<B**>(scp.vald_sc));
f3(reinterpret_cast<B**>(&scp.vald_sc));
return 0;
}
仅针对您的错误 改变这个
static_cast<Base*&>(derived);
to
static_cast<Base*>(derived);
^^
请参阅此处 http://ideone.com/1QuMLK
如果您想要参考,您需要做
Base* ptr = static_cast<Base*>(derived);
Base &ref = *ptr;
你不能将指针转换为引用 - 它们是完全不同的东西