使用继承函数转换bug

时间:2013-03-05 15:29:33

标签: c++ inheritance casting

我对使用c ++进行投射有疑问。我将通过一个例子来解释它。想象一下,我有两个班级:

class c1 {
  public:
  c1() {}

  double getHi() { return _hi; }  

private:
  double _hi = 2;
}

class c2 : c1 {
  public:
  c2() {}
} 

由于c2是c1的子节点,因此它继承了函数getHi()。因此,您可以使用c2实例调用getHi。

但如果你这样做会发生什么? :

c2* b = new c2();
cout << b->getHi() << endl;
cout << ((c1*)b)->getHi() << endl;

第一个将起作用。但不是第二个。为什么是这样?任何人都可以向我解释一下吗?

由于

编辑:这是一个例子。我写这篇文章时写了一个错字。

3 个答案:

答案 0 :(得分:2)

  

由于c2是c1的子元素,因此它将函数getHi()

首先,您应该说c2“派生自”,或“是派生类”,或“从(c1继承(在您的情况下是私下)。另外,“继承”是正确的动词。

  

但如果你做到这一点会发生什么?

在这种情况下,由于您从c1私下继承,因此无法执行转换。更改c2的定义如下,您将看到对getHi()的两次调用完全相同(在本例中):

class c2 : public c1 { };
//         ^^^^^^
//         This means that public members of c1 will become
//         public members of c2 as well. If you specify nothing,
//         public members of c1 will become private members of
//         c2 

请注意,您在类定义之后也缺少分号,最重要的是,publicc1定义中的c2访问修饰符:如果没有它们,构造函数将是private,因此您根本无法实例化这些类:

class c1
{
public: // <== Don't forget this!
  c1() {} // Btw, why this? It does nothing
  double getHi() { return _hi; }
private:
  double _hi = 2;
}; // <== Don't forget this!

class c2 : public c1
//         ^^^^^^ Don'f forget this!
{
public: // <== Don't forget this!
    c2() {} // Btw, why this? It does nothing
}; // <== Don't forget this!

int main()
{
    c2* b = new c2();
    b->getHi();          // Compiles, calls c1::getHi();
    ((c1*)b)->getHi();   // Compiles, calls c1::getHi();
}

答案 1 :(得分:0)

您声明c2的方式使c1成为c1私人基础:外部代码无法将b强制转换为c1因为这个。

要解决此问题,请将c1设为公共基地:

class c2: public c1 {
    ...
};

答案 2 :(得分:0)

使用c ++代码使用c样式转换的错误形式。使用static_cast&lt;&gt;或者也许是dynamic_cast&lt;&gt;代替。除此之外,您在示例中私下继承了c1。如果您将其更改为:

class c2 : public c1 {

它可能会更好。