将 class 的实例转换为其子 class 是否合法?
Is casting an instance of a class to its subclass legal?
是否将 class 转换为自身的子 class 而没有明确定义的附加数据字段?
例如,如果我想对最终用户隐藏某些仅供内部使用的方法,如下所示。
#include <string>
#include <iostream>
// public.hpp
class Talker {
public:
Talker(std::string text) {
this->text = text;
}
virtual void talk() {
std::cout << this->text << std::endl;
}
protected:
std::string text;
};
// private.cpp
class InnerTalker : public Talker {
public:
void setText(std::string text) {
this->text = text;
}
};
int main(int argc, char **argv) {
Talker t("Hello World!");
t.talk();
InnerTalker *ht = reinterpret_cast<InnerTalker *>(&t);
ht->setText("Farewell World!");
t.talk();
return 0;
}
我已经编译了这个例子,它按我预期的那样工作。打印:
Hello World!
Farewell World!
然而,这并不能使其成为明确定义的行为。
提前感谢您提供的任何信息。
来自cppreference:
Performing a class member access that designates a non-static data member or a non-static member function on a glvalue that does not actually designate an object of the appropriate type - such as one obtained through a reinterpret_cast - results in undefined behavior:
您可以执行 reinterpret_cast
,但是 几乎 任何使用结果指针的操作都会导致 UB。
是否将 class 转换为自身的子 class 而没有明确定义的附加数据字段?
例如,如果我想对最终用户隐藏某些仅供内部使用的方法,如下所示。
#include <string>
#include <iostream>
// public.hpp
class Talker {
public:
Talker(std::string text) {
this->text = text;
}
virtual void talk() {
std::cout << this->text << std::endl;
}
protected:
std::string text;
};
// private.cpp
class InnerTalker : public Talker {
public:
void setText(std::string text) {
this->text = text;
}
};
int main(int argc, char **argv) {
Talker t("Hello World!");
t.talk();
InnerTalker *ht = reinterpret_cast<InnerTalker *>(&t);
ht->setText("Farewell World!");
t.talk();
return 0;
}
我已经编译了这个例子,它按我预期的那样工作。打印:
Hello World!
Farewell World!
然而,这并不能使其成为明确定义的行为。
提前感谢您提供的任何信息。
来自cppreference:
Performing a class member access that designates a non-static data member or a non-static member function on a glvalue that does not actually designate an object of the appropriate type - such as one obtained through a reinterpret_cast - results in undefined behavior:
您可以执行 reinterpret_cast
,但是 几乎 任何使用结果指针的操作都会导致 UB。