Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在c+中有方法吗+;将指针强制转换为它所指向的实际类型?_C++_Casting_Typeid - Fatal编程技术网

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的实数类型动态地选择函数之间的函数。