使用 static_cast 的有用向下转换示例,它不会产生未定义的行为
Example of useful downcast with static_cast which does not produce undefined behaviour
我想知道在 没有未定义行为 的情况下,通过 static_cast
应用向下转换的简短代码示例。
我环顾四周,发现有很多文本(帖子、问答等)提到了标准的片段、解释等。
但我没有找到任何例子来说明这一点(这让我感到惊讶)。
谁能提供一个这样的例子?
一个非常基本的例子:
class Animal {};
class Dog : public Animal {};
void doSomething() {
Animal *a = new Dog();
Dog *d = static_cast<Dog*>(a);
}
一个更人为的例子:
class A { public: int a; };
class B : public A {};
class C : public A {};
class D : public B, public C {};
void doSomething() {
D *d = new D();
int bValue = static_cast<B*>(d)->a;
int cValue = static_cast<C*>(d)->a;
// This does not work because we have two a members in D!
// int eitherValue = d->a;
}
还有无数其他情况,由于程序中的某些标志或不变量,您知道实例的实际类型类型。但是,许多消息来源建议在所有情况下都首选 dynamic_cast
以避免错误。
通过 static_cast
进行的向下转换是 Curiously recurring template pattern (CRTP) 典型实现的一部分。来自 wikipedia 的示例:
template <class T>
struct Base
{
void interface()
{
// ...
static_cast<T*>(this)->implementation();
// ...
}
static void static_func()
{
// ...
T::static_sub_func();
// ...
}
};
struct Derived : Base<Derived>
{
void implementation();
static void static_sub_func();
};
Base
“知道”它可以通过 static_cast
(而不是 dynamic_cast
)将 this
向下转换为 T*
,因为 Base
将被 T
继承。有关 CRTP 的更多详细信息,请参阅维基百科文章。
我想知道在 没有未定义行为 的情况下,通过 static_cast
应用向下转换的简短代码示例。
我环顾四周,发现有很多文本(帖子、问答等)提到了标准的片段、解释等。
但我没有找到任何例子来说明这一点(这让我感到惊讶)。
谁能提供一个这样的例子?
一个非常基本的例子:
class Animal {};
class Dog : public Animal {};
void doSomething() {
Animal *a = new Dog();
Dog *d = static_cast<Dog*>(a);
}
一个更人为的例子:
class A { public: int a; };
class B : public A {};
class C : public A {};
class D : public B, public C {};
void doSomething() {
D *d = new D();
int bValue = static_cast<B*>(d)->a;
int cValue = static_cast<C*>(d)->a;
// This does not work because we have two a members in D!
// int eitherValue = d->a;
}
还有无数其他情况,由于程序中的某些标志或不变量,您知道实例的实际类型类型。但是,许多消息来源建议在所有情况下都首选 dynamic_cast
以避免错误。
通过 static_cast
进行的向下转换是 Curiously recurring template pattern (CRTP) 典型实现的一部分。来自 wikipedia 的示例:
template <class T> struct Base { void interface() { // ... static_cast<T*>(this)->implementation(); // ... } static void static_func() { // ... T::static_sub_func(); // ... } }; struct Derived : Base<Derived> { void implementation(); static void static_sub_func(); };
Base
“知道”它可以通过 static_cast
(而不是 dynamic_cast
)将 this
向下转换为 T*
,因为 Base
将被 T
继承。有关 CRTP 的更多详细信息,请参阅维基百科文章。