我有一个带有implements 2接口的类,并继承了1个类.所以,通常它看起来像这样:
class T : public A, public IB, public IC {
};
Run Code Online (Sandbox Code Playgroud)
代码中有一点我有一个IB *,但可以真正使用A *.我希望动态演员喜欢这样:
IB *b_ptr = new T; // it's really more complicated, but serves the example
A *a_ptr = dynamic_cast<A *>(b_ptr);
Run Code Online (Sandbox Code Playgroud)
不幸的是,这不起作用.有没有正确的方法来做到这一点?或者我应该实施一个解决方案?我已经考虑过这两个IB并且IC实际上是从遗传中继承的A,但是我上次尝试过IIRC时,有一些并发症使它变得不可取.
有什么想法吗?
编辑:哦,是的,这是一个插件API的一部分,所以不幸的是我没有直接访问T我需要的类型A *.我的例子彼此相邻,但如上所述,它更复杂.基本上我有2个共享库.T和T1(我有一个IB *)都是实现插件API的类,并且是共享库的内部.
澄清:这是我的典型插件的一个更具体的例子(它们在不同的库中):
插件A:
class PluginA : public QObject, public PluginInterface, public OtherInterface {
};
Run Code Online (Sandbox Code Playgroud)
插件B:
class PluginB : public QObject, …Run Code Online (Sandbox Code Playgroud) 几分钟前我正在回答一个问题,它又向我提出了另一个问题:
在我的一个项目中,我做了一些网络消息解析.消息的形式为:
[1 byte message type][2 bytes payload length][x bytes payload]
Run Code Online (Sandbox Code Playgroud)
有效负载的格式和内容由消息类型确定.我有一个基于公共类的类层次结构Message.
为了实例化我的消息,我有一个静态解析方法,它Message*根据消息类型字节返回一个.就像是:
Message* parse(const char* frame)
{
// This is sample code, in real life I obviously check that the buffer
// is not NULL, and the size, and so on.
switch(frame[0])
{
case 0x01:
return new FooMessage();
case 0x02:
return new BarMessage();
}
// Throw an exception here because the mesage type is unknown.
}
Run Code Online (Sandbox Code Playgroud)
我有时需要访问子类的方法.由于我的网络消息处理必须快速,我决定避免,dynamic_cast<>并且我向基 …
我有一段C++代码如下:
template <typename ...A>
struct CastAll{
template <typename ...B>
void cast_all(void(*fun)(B...), A...as){
//...
}
};
Run Code Online (Sandbox Code Playgroud)
我想要做的是以这样的方式实现cast_all:它将每个参数动态转换为B中的相应类型,然后使用"casted"参数调用给定的函数fun.
例如,在:
struct A{};
struct B : public A{};
void foo(B *b1, B *b2){
//... does something with b1 and b2
}
int main(){
A *a1 = new B();
A *a2 = new B();
CastAll<B*, B*> cast; //used to cast each A* to B*
cast.cast_all<B*, B*>(foo, a1, a2);
}
Run Code Online (Sandbox Code Playgroud)
cast_all应扩展为:foo(dynamic_cast(a1),dynamic_cast(a2));
我看过很多关于可变参数模板的文章.然而,几个小时后,我仍然无法弄明白.
有任何想法吗?
我有以下层次结构:
class base
{
public:
virtual ~base(){}
virtual void foo() {}
};
template <typename T>
class derived1 : public base
{
virtual void foo() {};
};
template <typename T>
class derived2 : public base
{
virtual void foo() {};
};
Run Code Online (Sandbox Code Playgroud)
现在给出一个指向base的指针,我想知道底层是derived1还是derived2.问题是derived1和derived2都可以专门用于许多不同类型,使用dynamic_cast来测试向下转换需要知道模板类型.我最终得到了凌乱,不稳定和不完整的代码:
base* b = new derived1<int>();
if (dynamic_cast<derived1<int>*> ||
dynamic_cast<derived1<unsigned int>*> ||
dynamic_cast<derived1<double>*>)
std::cout << "is derived1";
else if (dynamic_cast<derived2<int>*> ||
dynamic_cast<derived2<unsigned int>*> ||
dynamic_cast<derived2<double>*>)
std::cout << "is derived2";
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法,可以处理任何类型的专业化?
我看到一个奇怪的失败,dynamic_cast它NULL在clang编译器上返回.但是相同的代码正在使用gcc环境.
你能指点我可能是根本原因吗?dynamic_castllvm和gcc 之间有什么区别?
我正在使用编译器的默认行为,我认为默认情况下启用RTTI.
template<typename T> T*
find_msg_of_type(
MsgList *list
) {
T* msg = NULL;
if (list) {
for (std::vector<MsgList*>::iterator it = list->element.begin();
it != list->element.end();
it++) {// MsgList can be list of objects build with GSoap.
if (typeid(*(*it)) == typeid(T)) {
msg = dynamic_cast<T*>(*it); // Failing on clang but this same code is working with gcc compiler.
break;
}
}
}
return msg;
}
Run Code Online (Sandbox Code Playgroud)
还有一个观察:用gcc
if (typeid(*(*it)) == typeid(T))
Run Code Online (Sandbox Code Playgroud)
正如预期的那样完美地工作但是有铿锵声
if (typeid(*(*it)) …Run Code Online (Sandbox Code Playgroud) 我有以下代码:
vector<C1*>::iterator itr = vec.begin();
for (; itr != vec.end(); ++itr) {
C2 *c = dynamic_cast<C2*>(*itr);
c->f();
}
Run Code Online (Sandbox Code Playgroud)
我想知道我是否可以使用one-line for_each来替换它.我尝试了以下方法:
for_each(vec.begin(), vec.end(), bind2nd(mem_fun(&C2::f), dynamic_cast<C2*>));
Run Code Online (Sandbox Code Playgroud)
但是我收到编译错误,
expected unqualified-id before 'dynamic_cast'
Run Code Online (Sandbox Code Playgroud)
什么应该是正确的呢?
[编辑]我不能使用c ++ 11.看起来我必须定义一个额外的仿函数,叹息.
关于代码本身的一些问题:C1和C2是2个纯接口; f()仅作为C2的API提供.向量"vec"有一个具有C1和C2接口的对象列表,但它们作为C1*的向量传递给这段代码.
既铛3.5.0和克++ 4.9.0 编译下面的代码细(带-std=c++11 -Wall -Wextra -pedantic-errors)和程序输出true:
#include <iostream>
struct A
{
virtual ~A() = default;
};
struct B
{
virtual ~B() = default;
};
struct C : A, B
{
virtual ~C() = default;
};
int main()
{
C c;
A* ap = &c;
B* bp = dynamic_cast<B*>(ap);
std::cout << std::boolalpha << (bp != nullptr) << std::endl;
}
Run Code Online (Sandbox Code Playgroud) 我现在正在阅读Scott Meyers的"更有效的C++".启发性!第2项提到dynamic_cast不仅可以用于downcast,也可以用于兄弟演员.可以请任何人为兄弟姐妹提供一个(合理的)非人为的例子吗?这个愚蠢的测试打印0应该是,但我无法想象任何这种转换的应用程序.
#include <iostream>
using namespace std;
class B {
public:
virtual ~B() {}
};
class D1 : public B {};
class D2 : public B {};
int main() {
B* pb = new D1;
D2* pd2 = dynamic_cast<D2*>(pb);
cout << pd2 << endl;
}
Run Code Online (Sandbox Code Playgroud) 我有一些带有通用接口的代码,我需要在其中进行强制转换.我现在正试图转换为智能指针,但遇到了一些错误.下面的代码重现了这个问题.我正在使用C++ 14,所以我认为这些东西现在应该自动运行了吗?
#include <memory>
#include <iostream>
int main()
{
std::shared_ptr<int> a(new int);
*a = 5;
std::shared_ptr<void> b = std::dynamic_pointer_cast<void>(a);
std::shared_ptr<int> c = std::dynamic_pointer_cast<int>(b);
std::cout << *c; //should be 5
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试编译它时,我得到:
Error C2680 '_Elem1 *': invalid target type for dynamic_cast
Error C2681 'int *': invalid expression type for dynamic_cast
Run Code Online (Sandbox Code Playgroud)
猜猜我在语法上做了些蠢事?
我可以理解为什么dynamic_cast在这种情况下有效:
#include <iostream>
struct A{
virtual ~A() = default;
};
struct B {
virtual ~B() = default;
};
struct C : A, B{};
void f(const A &a) {
if(auto p = dynamic_cast<const B*>(&a))
std::cout << "a is a B" << std::endl;
}
int main() {
f(C{});
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是为什么如果你从B中删除多态,它仍然有效:
#include <iostream>
struct A{
virtual ~A() = default;
};
struct B {
};
struct C : A, B{};
void f(const A &a) {
if(auto p = dynamic_cast<const B*>(&a))
std::cout << …Run Code Online (Sandbox Code Playgroud) c++ ×10
dynamic-cast ×10
casting ×3
inheritance ×3
c++11 ×2
clang ×1
compilation ×1
downcast ×1
foreach ×1
llvm ×1
polymorphism ×1
siblings ×1
static-cast ×1
templates ×1
vptr ×1
vtable ×1