Dynamic_cast问题:typeid对象不相等,但名称相等
dynamic_cast issues: typeid object is not equal, but name is equal
我发现dynamic_cast
没有在我期望的情况下工作,并且在运行时查看对象的typeid
使情况更加不清楚。我只是想从基到派生的转换,我不明白为什么它不起作用。
我有一个像这样的类结构:
class BoundaryCondition {
public:
virtual void DoSomething() = 0;
virtual ~BoundaryCondition() { /* * */ }
}
class ReflectingBc : BoundaryCondition {
public:
virtual void DoSomething();
}
class MarshakBc : BoundaryCondition {
public:
virtual void DoSomething();
MarshakBc(double value);
void changeValueLaterOn(double value);
private:
double value_;
}
我(本质上)有一个std::vector<BoundaryCondition*>
,它表示问题部分的边界条件。我希望能够取vector
,并将其中的所有MarshakBc
对象称为changeValueLaterOn
。所以我有一个像
for (std::vector<BoundaryCondition*>::iterator bc = bcPtrs_.begin();
bc != bcPtrs_.end(); ++bc)
{
if (std::string(typeid(MarshakBc).name()) == std::string(typeid(**bc).name()) )
{
std::cerr << "SAME! ";
}
if (typeid(MarshakBc) != typeid(**bc))
{
std::cerr << "NOT SAME ";
}
MarshakBc* thisBc = dynamic_cast<MarshakBc*>( &( **bc ) );
if (thisBc == NULL) {
std::cerr << "...nothingn";
continue;
}
thisBc->changeValueLaterOn( 1.23);
std::cerr << "...set!n";
}
如果我的向量包含一个ReflectingBc*
,然后一个MarshakBc*
,我的输出看起来像:
NOT SAME ...nothing
SAME! NOT SAME ...nothing
我是否误解了dynamic_cast
和typeid
?
[实际情况比这更复杂,因为BoundaryCondition
的定义与上面的代码在不同的翻译单元中,并且涉及模板等,但上面的代码非常代表我正在做的事情和我得到的结果]
更多细节
下面是我的实际例程,它在函子内部使用,LoAnisoBc
是派生类,BoundaryConditionT
是基类:
template<class SnTraits_T, class LoTraits_T>
void FillLoAnisoBcs<SnTraits_T, LoTraits_T>::operator() (
const BoundaryFaceT& bf,
BoundaryConditionT& bc)
{
std::cerr << "Want " << typeid(LoAnisoBc).name() << "n";
std::cerr << "Chkg " << typeid(bc).name() << "n";
if (std::string(typeid(LoAnisoBc).name()) == std::string(typeid(bc).name()) )
{
std::cerr << " SAME!";
}
if (!(typeid(LoAnisoBc) == typeid(bc))) {
std::cerr << "...nothingn";
}
// if we're not an "anisotropic BC", don't do anything
LoAnisoBc* anisoBc = dynamic_cast<LoAnisoBc*>( &bc );
if (anisoBc == NULL) {
std::cerr << "...nothingn";
return;
}
anisoBc->setFCoeff( fCoeff_ );
std::cerr << "; set fCoeff = " << fCoeff_ << "n";
}
这里是输出
Want N6detLib17cellDiffusionOned28AnisotropicBoundaryConditionE
Chkg N6detLib17cellDiffusionOned27ReflectingBoundaryConditionE
NOT SAME...nothing
Want N6detLib17cellDiffusionOned28AnisotropicBoundaryConditionE
Chkg N6detLib17cellDiffusionOned28AnisotropicBoundaryConditionE
SAME! NOT SAME...nothing
所以bcPtrs_
结构和边界条件在一个动态库中(所以它是Python中的一个模块),FillLoAnisoBcs
的实例化在另一个动态库中。Erik认为这是一个可能的问题,我同意。
当你跨越库边界时,typeid
的行为很奇怪-例如:typeid何时可以为同一类型返回不同的type_info实例?在某些情况下。特别是,在linux上,您将需要-rdynamic
来确保库中的type info对象不会被删除,从而使使用库的可执行文件无法访问。
我最好的猜测:
在您看到LoAnisoBc
定义的可执行文件中,存在LoAnisoBc
的type_info
实例。在LoAnisoBc
所属的库中,存在另一个type_info
实例。type_info
的operator==
很可能实现为一个简单的指针比较。因此,当您获得静态LoAnisoBc
表达式的typeid时,您获得的是可执行实例,而引用生成的是库实例—相同的名称,但不是相同的实例。
- 两个字符串在 c++ 中不相等
- 如何以优化的方式同时迭代两个间距不相等的数组
- 如何在不销毁对象的情况下返回对象列表
- 当 std::move 与 C 样式数组或不移动对象时会发生什么
- 通用参考 l 值不复制对象
- 如何在类中递增单独的变量,而不是对象本身?
- 是否确保 2 个连续的 std::chrono::steady_clock::now() 不相等?
- 需要实例化不同类/对象并在启动时确定的硬件插槽的设计模式
- C ++相同的字符串不相等(实际上是char*)
- 在 c++ 中使用字符串变量选择静态类结构,而不带对象
- 双指针在使用 new 时不调用对象构造函数
- 生成文件不构建对象,我告诉它如何
- 如何获取指向类(而不是对象)的引用/指针
- C ++:如何在不创建对象的情况下在主函数中调用方法
- 在 c++ 中比较不相等数组或字符串的方法
- C++ - 空的 std::list begin() 和 end() 不相等
- 将数据从一个类传递到另一个类而不传递对象
- 变量如何在不创建对象的情况下获得内存
- 为什么我的函数不改变对象的属性
- Dynamic_cast问题:typeid对象不相等,但名称相等