0

我编写了一个重载的插入运算符,它返回一个对象的所有数据。出于某种原因,当我试图称它为 ie 时。cout << *pkgArray[index] 它什么也不显示,但是如果我在没有 * 的情况下执行它,它会返回一个内存地址。下面是重载的运算符和我使用它的尝试。

ostream& operator<<(ostream& o, const OverNight& bObj) {
  stringstream ss;
  ss << bObj.getAddress() <<  ", " << bObj.getCity() << ", " << bObj.getState() << ", "     << bObj.getZip();
  string fullAddress = ss.str();
  ss.str("");
  int newWeight = bObj.getWeight();
  ss << "$" << bObj.getUnitPrice() + bObj.getAdditional() << "/ounce";
  string costPerOunce = ss.str();
  o << left 
      << setw(1) << "|"
      << setw(20) << bObj.getsname() 
      << setw(1) << "|"
      << setw(20) << bObj.getName() 
      << setw(1) << "|"
      << setw(60) << fullAddress 
      << setw(1) << "|" 
      << setw(10) << bObj.getType()
      << setw(1) << "|"
      << setw(10) << costPerOunce
      << setw(1) << "|"
      << endl;
  o << left << "+" << setfill('-') << setw(136) << right << "+" << endl;
  o << setfill(' '); // clears the hyphen filler.
  return o;
  } 

int main() {
    Package *pkgArray[15]; // package class is abstract.
    OverNight *onObj; // assigned to pkgArray later on.
    TwoDay *tdObj; // assigned to pkgArray later on.


    // pkgArray is a pointerArray filled with objects of 2 derived classes.
    for (int index = 0; index < max; index++) {
        cout << pkgArray[index];
    }
}

我试过*pkgArray[index]和&pkgArray[index],后者返回一个内存地址,第一个什么也不返回。我对 c++ 相当陌生,感觉我已经尝试了一切来解决这个问题。

编辑:我添加了 pkgArray 的声明和分配给它的对象。我无法根据作业使用向量。

在进一步研究问题后,我发现正在发生的事情,是重载的运算符没有处理正在传递的对象。我已经尝试取消引用 pkgArray,并完成了基类中重载的插入运算符的功能,这很有效。现在我的问题是我需要从动态数组中取出派生类的对象。我尝试在取消引用时应用优先级,但无济于事。声明如下。

过夜 * onObj; // 将被分配派生类对象的指针。两天 * tdObj; // 将被分配派生类对象的指针 Package * pkgArray[15]; // 这是一个Package类型的动态数组,它是基类

在创建过夜对象和两天对象后,它们被分配给包数组。

我正在尝试运行一个循环,该循环使用存储在动态数组中的派生对象调用重写的 << 运算符。在完成这项任务的过程中,我学到了很多东西,但显然还不足以解决这个问题。

4

3 回答 3

1

对多态层次结构中的对象进行 I/O 的通常模式并不是很明显。你通常大致这样实现它:

#include <iostream>
#include <vector>

class Base {
public:
    virtual std::ostream &write(std::ostream &os) const {
        return os << "Base\n";
    }
};

class D1 : public Base {
public:
    virtual std::ostream &write(std::ostream &os) const {
        return os << "Derived 1\n";
    }
};

class D2 : public Base {
public:
    virtual std::ostream &write(std::ostream &os) const {
        return os << "Derived 2\n";
    }
};

std::ostream &operator<<(std::ostream &os, Base const &b){
    return b.write(os);
}

int main(){
    std::vector<Base *> objects;
    Base b;
    D1 d1;
    D2 d2;

    objects.push_back(&b);
    objects.push_back(&d1);
    objects.push_back(&d2);

    for (int i=0; i<3; i++)
        std::cout << *objects[i];
    return 0;
}

在这种情况下,结果是:

Base
Derived 1
Derived 2

......正如你所希望的那样。

于 2012-04-26T16:38:50.553 回答
0

*pkgArray[index]尝试取消引用未定义为指针的对象,因此 * 对编译器没有意义(它使用指针变量中包含的第一个字节和类型描述来解释位于内存中的数据,这对它来说只是字节直到通过取消引用提供更多信息)。

您可能正在接收尚未为重载的 ostream 定义正确解释的对象引用。

于 2012-04-26T16:46:24.143 回答
0

我已经弄清楚发生了什么。当我将派生类的对象分配给基类类型的动态数组时,只有内存地址被存储为基类类型。因此,当我运行循环时,我只能获取基类(包)类型的对象,因此,正在寻找 OverNight 类型对象的重载运算符永远不会被调用。

于 2012-04-27T01:20:16.220 回答