[英]is there a way in c++ to cast a pointer to the real type it points to?
Edited. 编辑。 see below.
见下文。
Consider the following situation - I have a base class and some derived ones : 考虑以下情况-我有一个基类和一些派生类:
class B {...[virtual...]...};
class D1 : public B {...};
class D2 : public B {...};
and I have a function that suppose to behave differently on each of them (implement-wise. conceptually, they all do the same thing). 并且我有一个函数,假定它们在每个函数上的行为都不同(从实现角度来看,从概念上讲,它们都做同样的事情)。 now, I would of course implement an auxiliary function for each :
现在,我当然会为每个实现一个辅助功能:
void f_aux (B * b);
void f_aux (D1 * d1);
void f_aux (D2 * d2);
and then I can implement the main function by doing something like this : 然后我可以通过执行以下操作来实现主要功能:
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); }
}
now, my question is - can I do this in a general way, meaning something like : 现在,我的问题是-我能以一般方式执行此操作吗,意思是:
void f (B * bd1d2) {
f_aux(CAST_TO_REAL_TYPE(bd1d2));
}
I tried using typeid directly which of course failed. 我尝试直接使用typeid当然失败了。 I tried searching that online and nothing came up..
我尝试在网上搜索,但没有任何反应。
so, Is there a way of doing it? 所以,有办法吗? and if there isn't, than why?
如果没有,那为什么呢?
many thanks.. 非常感谢..
Edit : 编辑:
I tried to simplify the problem, and it seems that I've done the opposite.. Let me try again : In the real settings, I have 3 classes : Line, Ray and Segment, and I'd like another class (a Graph-Edge) to hold a general pointer to an object any of the types - meaning, it has a field that can be either Line Ray or Segment. 我试图简化问题,似乎我做了相反的事情。让我再试一次:在实际设置中,我有3个类:Line,Ray和Segment,我想要另一个类(一个Graph -Edge)以保存指向任何类型对象的通用指针-表示该对象的字段可以是Line Ray或Segment。 Now, I'd like to have the option to get an intersection point of 2 Graph-Edges, or of a Graph-Edge with a given Line/Ray/Segment without dealing with the question of "what kind of an edge is this?"
现在,我想选择获取2个Graph-Edges的交点,或获得具有给定Line / Ray / Segment的Graph-Edge的交点,而无需处理“这是哪种边缘? “ on none of the two.
两者都不是。 I would also like to have my Geometry classes as generic as possible, even if some of the functionality is not necessary in Graph-Edges.. So I made a super-class : LinearObject, with a virtual getCut(LinearObject & lo) function, and followed the answers below, and the best I've got so far is this :
我还希望我的Geometry类尽可能通用,即使在Graph-Edges中某些功能不是必需的。因此,我制作了一个超类:LinearObject,带有一个虚拟的getCut(LinearObject&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;
}
It works, but, can I do any better (Eleganltly) ? 它有效,但是,我能做得更好吗?
Edit: Edit after you question edit, hope I understand everything you want... 编辑:在您提出问题后进行编辑,希望我了解您想要的一切...
#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;
}
End of edit. 编辑结束。
If you can implement f_aux
inside the class, just take advantage of polymorphism: 如果可以在类内部实现
f_aux
,则只需利用多态性即可:
class B {
/* ...[virtual...]... */
virtual void f_aux () { /* ... */ }
};
class D1 : public B {
/* ... */
virtual void f_aux () { /* ... */ }
};
class D2 : public B {
/* ... */
virtual void f_aux () { /* ... */ }
};
Then just do: 然后做:
void f (B * bd1d2) {
bd1d2->f_aux () ; // Will call the correct function depending on what bd1d2 points to
}
Edit: To answer your comment, if you want to have something like d->f_aux(b)
just add an intermediate class D
: 编辑:要回答您的评论,如果您想拥有
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) ;
The "correct" solution for this is to do something like is to use virtual functions: 为此,“正确”的解决方案是使用虚函数:
void f_aux (B * b)
{
b->do_f_aux();
}
where you declare do_f_aux
as 您将
do_f_aux
声明为
class B
{
...
virtual void do_f_aux() { ... };
}
and of course implement the do_f_aux
differently in d1
and d2
. 并且当然在
d1
和d2
do_f_aux
不同的方式实现do_f_aux
。
[This assumes you need f_aux
as a standalone function - if you just need a function that does this, then just call the virtual function f_aux
, and call it directly in the f
as bd1d2->f_aux()
] [这假设您需要
f_aux
作为独立函数-如果您只需要一个执行此功能的函数,则只需调用虚拟函数f_aux
,并直接在f
bd1d2->f_aux()
其作为bd1d2->f_aux()
调用]
Edit: 编辑:
Casting objects in the way you describe is a "bad smell" ( http://en.wikipedia.org/wiki/Code_smell ) - a symptom of "you're doing it wrong". 以您描述的方式投射对象是一种“难闻的气味”( http://en.wikipedia.org/wiki/Code_smell)-一种“您做错了”的症状。 It can almost always be avoided by using virtual functions.
使用虚函数几乎总是可以避免这种情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.