C++ 在c+中有方法吗+;将指针强制转换为它所指向的实际类型?
已编辑。见下文。 考虑以下情况- 我有一个基类和一些派生类:C++ 在c+中有方法吗+;将指针强制转换为它所指向的实际类型?,c++,casting,typeid,C++,Casting,Typeid,已编辑。见下文。 考虑以下情况- 我有一个基类和一些派生类: class B {...[virtual...]...}; class D1 : public B {...}; class D2 : public B {...}; 我有一个函数,它假设每个函数的行为都不同(实现方面,从概念上讲,它们都做相同的事情)。 现在,我当然要为每一个实现一个辅助功能: void f_aux (B * b); void f_aux (D1 * d1); void f_aux (D2 * d2); 然后
class B {...[virtual...]...};
class D1 : public B {...};
class D2 : public B {...};
我有一个函数,它假设每个函数的行为都不同(实现方面,从概念上讲,它们都做相同的事情)。
现在,我当然要为每一个实现一个辅助功能:
void f_aux (B * b);
void f_aux (D1 * d1);
void f_aux (D2 * d2);
然后我可以通过这样做来实现主要功能:
void f (B * bd1d2) {
if (typeid(bd1d2) == typeid(B*) { f_aux((B*)bd1d2); }
else if (typeid(bd1d2) == typeid(D1*) { f_aux((D1*)bd1d2); }
else if (typeid(bd1d2) == typeid(D2*) { f_aux((D2*)bd1d2); }
}
现在,我的问题是——我能用一般的方式来做吗,意思是:
void f (B * bd1d2) {
f_aux(CAST_TO_REAL_TYPE(bd1d2));
}
我尝试直接使用typeid,当然失败了。
我试着在网上搜索,结果一无所获
那么,有没有办法做到这一点?如果没有,为什么
非常感谢
编辑:
我试图简化这个问题,但似乎我做了相反的事情。。
让我再试一次:
在实际设置中,我有3个类:Line、Ray和Segment,我想要另一个类(Graph Edge)来保存指向任何类型的对象的通用指针——也就是说,它有一个字段,可以是Line Ray或Segment。
现在,我希望可以选择得到两条图边的交点,或者一条图边与给定的线/光线/线段的交点,而不需要处理“这是什么样的边?”的问题。
我还希望我的几何体类尽可能通用,即使图形边中不需要某些功能。。
所以我制作了一个超级类:linearbject,带有一个虚拟getCut(linearbject&lo)函数,并遵循下面的答案,到目前为止我得到的最好结果是:
class Line;
class Segment;
class LinearObject {
public :
virtual void getCut(LinearObject * lo) { printf("lo->lo\n"); }
private :
virtual void getCut_aux(Line * l) = 0;
virtual void getCut_aux(Segment * s) = 0;
friend class Line; friend class Segment;
};
class Line : public LinearObject {
public :
void getCut(LinearObject * lo) { printf("l->lo\n"); lo->getCut_aux(this); }
private :
void getCut_aux(Line * l) { printf("l->l\n"); }
void getCut_aux(Segment * s) { printf("l->s\n"); }
};
class Segment : public LinearObject {
public :
void getCut(LinearObject * lo) {
printf("s->lo\n");
lo->getCut_aux(this);
}
private :
void getCut_aux(Line * l) { printf("s->l\n"); }
void getCut_aux(Segment * s) { printf("s->s\n"); }
};
int main() {
Line l; Segment s;
LinearObject *lop = &l, *lop2 = &s;
lop->getCut(lop2);
s.getCut(&l);
return 0;
}
它可以工作,但是,我能做得更好吗(电子版)?编辑:在你提问编辑后编辑,希望我能理解你想要的一切
#include <cstdio>
class Line;
class Segment;
class LinearObject {
protected :
virtual void getCut_aux(LinearObject *) { printf("LinearObject->getCut_aux\n") ; }
friend class LinearObject_ ;
};
class LinearObject_ : public LinearObject {
public:
void getCut (LinearObject * lo) { printf("getCut()\n"); lo->getCut_aux(this) ; }
};
class Line : public LinearObject_ {
protected :
virtual void getCut_aux(LinearObject *) { printf("Line->getCut_aux\n") ; }
};
class Segment : public LinearObject_ {
protected:
virtual void getCut_aux(LinearObject *) { printf("Segment->getCut_aux\n") ; }
};
int main() {
Line l; Segment s;
LinearObject *lop = &l, *lop2 = &s;
l.getCut(lop2);
s.getCut(&l);
return 0;
}
那么就做:
void f (B * bd1d2) {
bd1d2->f_aux () ; // Will call the correct function depending on what bd1d2 points to
}
Edit:要回答您的评论,如果您想要类似d->f_aux(b)
的内容,只需添加一个中间类d
:
class D {
void f (B *b) { b->f_aux(this) ; }
};
class D1 : public B, public D { /* ... */ };
B *pdb = new B (), *pd3 = new D3 () ;
D1 *pd1 = new D1 () ;
D2 *pd2 = new D2 () ;
pd1->f(b) ;
pd2->f(pd3) ;
编辑:在您提出编辑问题后进行编辑,希望我了解您想要的一切
#include <cstdio>
class Line;
class Segment;
class LinearObject {
protected :
virtual void getCut_aux(LinearObject *) { printf("LinearObject->getCut_aux\n") ; }
friend class LinearObject_ ;
};
class LinearObject_ : public LinearObject {
public:
void getCut (LinearObject * lo) { printf("getCut()\n"); lo->getCut_aux(this) ; }
};
class Line : public LinearObject_ {
protected :
virtual void getCut_aux(LinearObject *) { printf("Line->getCut_aux\n") ; }
};
class Segment : public LinearObject_ {
protected:
virtual void getCut_aux(LinearObject *) { printf("Segment->getCut_aux\n") ; }
};
int main() {
Line l; Segment s;
LinearObject *lop = &l, *lop2 = &s;
l.getCut(lop2);
s.getCut(&l);
return 0;
}
那么就做:
void f (B * bd1d2) {
bd1d2->f_aux () ; // Will call the correct function depending on what bd1d2 points to
}
Edit:要回答您的评论,如果您想要类似d->f_aux(b)
的内容,只需添加一个中间类d
:
class D {
void f (B *b) { b->f_aux(this) ; }
};
class D1 : public B, public D { /* ... */ };
B *pdb = new B (), *pd3 = new D3 () ;
D1 *pd1 = new D1 () ;
D2 *pd2 = new D2 () ;
pd1->f(b) ;
pd2->f(pd3) ;
“正确”的解决方案是使用虚拟函数:
void f_aux (B * b)
{
b->do_f_aux();
}
您在此处声明do\u f\u aux
为
class B
{
...
virtual void do_f_aux() { ... };
}
当然,在d1
和d2
中以不同的方式实现do\f\u aux
[这假设您需要作为一个独立函数的f_aux
-如果您只需要一个这样做的函数,那么只需调用虚拟函数f_aux
,并在f
中直接调用它作为bd1d2->f_aux()
]
编辑:
按你描述的方式投射物体是一种“臭味”()-一种“你做错了”的症状。使用虚拟函数几乎总是可以避免这种情况。正确的解决方案是使用虚拟函数:
void f_aux (B * b)
{
b->do_f_aux();
}
您在此处声明do\u f\u aux
为
class B
{
...
virtual void do_f_aux() { ... };
}
当然,在d1
和d2
中以不同的方式实现do\f\u aux
[这假设您需要作为一个独立函数的f_aux
-如果您只需要一个这样做的函数,那么只需调用虚拟函数f_aux
,并在f
中直接调用它作为bd1d2->f_aux()
]
编辑:
按你描述的方式投射物体是一种“臭味”()-一种“你做错了”的症状。几乎总是可以通过使用虚拟函数来避免这种情况。你必须在类外实现
f_aux
函数吗?@Holt不完全是这样。我将发布一个更详细的答案作为对你答案的评论。你必须在课堂之外实现f_aux
函数吗?@Holt不完全是这样。我将发布一个更详细的答案作为对你答案的评论。这实际上是对真实情况的简化。在实际问题中,我想在B的两个驱动变量实例之间实现一个二进制函数。用法类似于:p1->f(p2),其中p1,p2可以指向D1,D2,D3等。但是p1,p2将始终定义为B*。我想我可以按照你的建议做一些事情,比如:void D#:::f(B*B){return B->f#aux(this);},对吗?但是我确实想要一些更一般、更少黑客的东西…@elad:我认为解决方案是将f_aux
分为两部分:第一个参数部分和第二个参数部分。@elad为什么要在hacky类中定义f
?@Holt,因为它让我在基类中声明“不必要的”纯虚拟辅助函数,每个派生类都有一个,一般来说,我希望C++也知道通过指针/引用参数的实际类型动态选择函数,或者在LeAT提供一个干净的选项来强制这样的动作。嗯,它比typeid上的if-else稍微好一点。再次感谢..@Dani,我不明白你的意思。。函数f是关于两个对象之间的关系。我该如何分割呢?这实际上是对真实情况的简化。在实际问题中,我想在B的两个驱动变量实例之间实现一个二进制函数。用法类似于:p1->f(p2),其中p1,p2可以指向D1,D2,D3等。但是p1,p2将始终定义为B*。我想我可以按照你的建议做一些事情,比如:void D#:::f(B*B){return B->f#aux(this);},对吗?但是我确实想要一些更一般、更少黑客的东西…@elad:我认为解决方案是将f_aux
分为两部分:第一个参数部分和第二个参数部分。@elad为什么要在hacky类中定义f
?@Holt,因为它让我在基类中声明“不必要的”纯虚拟辅助函数,每个派生类都有一个,一般来说,我希望C++也知道通过p的实数类型动态地选择函数之间的函数。