6

我正在编写一个指向派生类的指针的程序。这是我的代码,

 #include <iostream>
    using namespace std;

    class base {
      int i;
    public:
      void set_i(int num) { i=num; }
      int get_i() { return i; }
    };

    class derived: public base {
      int j;
    public:
      void set_j(int num) {j=num;}
      int get_j() {return j;}
    };

    int main()
    {
      base *bp;
      derived d[2];

      bp = d;

      d[0].set_i(1);
      d[1].set_i(2);

      cout << bp->get_i() << " ";
      bp++; 
      cout << bp->get_i(); 

      return 0;
    }

程序显示 1 个正确值和其他垃圾值,因为

bp++;

正在递增指针以指向类基类型但不是类派生类型的下一个对象。

我们可以通过写作正确显示答案

> bp =& d[0];   
bp1=&d[1];  
 d[0].set_i(1);  
 d[1].set_i(2);

但是我们必须分配 2 个指针。类似地,如果我们必须取 100 个值,那么我们必须分配 100 个指针。这不好。

我的问题是我们可以通过单指针显示数组的值吗?

4

5 回答 5

7

我想 OP 试图这样做的原因是为了让他可以拥有一个对象数组,这些对象可以是某个基类的任意派生实例,并迭代它们。如果是这种情况,您确实需要一个指向基类的指针数组。就像是:

class Base { /* ... */ };
class Derived1 : public Base { /* ... */ };
class Derived2 : public Base { /* ... */ };

// ...

Base *arr[10] = {new Derived1(), new Derived1(), new Derived2(), ...};

// ...

for(Base **p = arr; p < arr+10; ++p) {
  *p->foo();
  // ...
}

如果我猜到了 OP 的真正问题,我认为这会解决它。

于 2013-08-30T19:51:17.007 回答
3

你不能做你想做的事。

您正在创建一个具有派生大小的对象数组。当您使用指向数组的基指针时,您试图将指针移动基数的大小。如果你有一个 Derived * 数组,那么你可以用一个基 * * 指向它们,一切都会正常工作。如果您有实际对象,则必须使用正确的数据类型。

您想要完成此操作的唯一原因是利用基类的多态特性。多态性仅适用于指针并以任何方式引用,因此存储实际对象对您几乎没有什么好处。

于 2013-08-30T19:43:32.040 回答
2

如果您坚持使用基类指针来指向派生类,则不能使用 ++ 进行迭代。你应该做这个:

bp = d;
.
.
.
bp = &d[1];
于 2013-08-30T19:46:35.217 回答
1

在 C/C++/ObjectiveC 中,大小总是隐含的。对于单一类型,编译器知道它的大小,同样,它通过指针的类型知道指针指向的对象的大小。因此,递增指针总是向指针添加编译时间常数;它不可能不同,因为在内存中的任何地方都没有存储大小之类的东西。因此,每当您将一个指针从一个类转换到另一个类时,您就不能再对其使用指针算术,否则您会得到未定义的行为。

作为解决方案,请使用 ShighShagh 的答案并使用指针数组。

于 2013-08-30T20:33:55.190 回答
1
  • 在 C++ 中,您可以使用指针作为数组来存储不同类型的对象。
  • 要创建数组指针,您只需声明指针变量并使用 MALLOC 或 NEW 分配内存。所以你会有;
  • base *bp = (base *)malloc(sizeof(10)/sizeof(base));
  • 这将创建一个大小为 10 的指针数组。然后您可以使用此指针来存储基础对象或派生对象。您还可以使用 for 循环遍历 10 个元素的指针。
于 2013-08-30T22:09:05.623 回答