gpt4 book ai didi

c++ - 共享库中模板化类和 dynamic_cast 的显式实例化

转载 作者:可可西里 更新时间:2023-11-01 16:10:51 25 4
gpt4 key购买 nike

今天我遇到了一个我似乎无法解决的问题。我正在编译一个共享库,其中包含一个模板化类( Derived<T> ,其基础是 Base )和此类的一些显式实例化。我希望图书馆用户从这个模板化类中扩展。当我尝试 dynamic_cast 时出现问题来自 Base* 的用户实例至 Derived<T>* .

我已经将问题缩小到这个 MWE:

共享库包含以下文件:

Base.h

#ifndef BASE_H_
#define BASE_H_

class Base {
public:
Base();
virtual ~Base();
};

#endif /* BASE_H_ */

Derived.h

#ifndef DERIVED_H_
#define DERIVED_H_
#include <Base.h>

template <typename T>
class Derived : public Base {
public:
Derived();
virtual ~Derived();
};

#endif /* DERIVED_H_ */

Derived.cpp

#include <Derived.h>

template <typename T>
Derived<T>::Derived() :
Base() {
}

template <typename T>
Derived<T>::~Derived() {
}

// explicit instantiations
template class Derived<float>;
template class Derived<double>;
template class Derived<long double>;

Helper.h

#ifndef HELPER_H_
#define HELPER_H_

#include <Base.h>

class Helper {
public:
Helper(Base* m);
virtual ~Helper();

};

#endif /* HELPER_H_ */

Helper.cpp

#include <Helper.h>
#include <Base.h>
#include <Derived.h>

#include <iostream>

using namespace std;

Helper::Helper(Base* m) {

cout << "after received " << m << endl;
cout << "after fom: " << dynamic_cast< Derived<float>* >(m) << endl;
cout << "after dom: " << dynamic_cast< Derived<double>* >(m) << endl;
cout << "after ldom: " << dynamic_cast< Derived<long double>* >(m) << endl;
cout << "===" << endl;
}

Helper::~Helper() {
}

使用该库的简单代码可以是:

测试.cpp

#include <Derived.h>
#include <Helper.h>

#include <iostream>

using namespace std;

class MyModel : public Derived<double> {
public:
MyModel() : Derived<double>() {
};

virtual ~MyModel() {
};

};

int main(int argc, char *argv[]) {

MyModel om1;
cout << "created mymodel " << &om1 << endl;
cout << "before fom: " << dynamic_cast< Derived<float>* >(&om1) << endl;
cout << "before dom: " << dynamic_cast< Derived<double>* >(&om1) << endl;
cout << "before ldom: " << dynamic_cast< Derived<long double>* >(&om1) << endl;
cout << "===" << endl;
Helper root(&om1);

return 0;
}

问题是当我创建共享库并链接 test.cpp 时反对它,dynamic_cast失败。这是一个示例输出:

created mymodel 0x7fff5fbff3e0
before fom: 0
before dom: 0x7fff5fbff3e0
before ldom: 0
===
after received 0x7fff5fbff3e0
after fom: 0
after dom: 0 // <<< Here I expected it to succeed and return a non-null pointer
after ldom: 0
===

但是,如果我将整个库和示例一起编译,则转换成功:

created mymodel 0x7fff5fbff3e0
before fom: 0
before dom: 0x7fff5fbff3e0
before ldom: 0
===
after received 0x7fff5fbff3e0
after fom: 0
after dom: 0x7fff5fbff3e0
after ldom: 0
===

我的问题是:为什么 dynamic_cast失败了?

而且,在我想保持类结构如示例的前提下,继续使用共享库:如何才能成功获取到Derived<some type>*?从 Base* 转换?

最佳答案

我假设您使用的是 Linux/GCC,因为在 Windows 上它应该“正常工作”。

它不能“仅适用于”GCC,因为 GCC 中的性能 RTTI 支持依赖于指针比较。这一切都在this GCC FAQ中解释。 ,包括如何解决。编辑:不过,这个 FAQ 说它不适用于 dlopen() 而与共享库的显式链接应该有效;所以也许还有其他问题,例如下面提到的错误。

我发现的一些其他链接可能有帮助:
dynamic_cast an interface from a shared library which was loaded by lt_dlopen(libtool) doesn't work
dynamic cast with interfaces
C++ dynamic_cast bug in Mac OS 10.6 Snow Leopard

关于c++ - 共享库中模板化类和 dynamic_cast 的显式实例化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6112362/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com