CHawk
CHawk

Reputation: 1356

C++ - When to exactly use ->? Error: base operand of ‘->’ has non-pointer type ‘BaseBond’

Getting some really confusing errors and not sure exactly why. Here is my code:

//=====================WORKS=======================
TradingBook::TradingBook(const char* yieldCurvePath, const char* bondPath)
{
//...Some stuff
    BaseBond* tradingBook[bondCount];

    for (int i=0; i < bondCount; i++)
    {
        tradingBook[i] = new CouponBond(bonds[i]);

        printf("Bond: %s\n"
           "  Price: %.3f\n"
           "  DV01: %.3f\n"
           "  Risk: %.3f\n", tradingBook[i]->getID(), tradingBook[i]->getPrice(), tradingBook[i]->getDV01(), tradingBook[i]->getRisk());
    }
}

//=================DOESNT WORK======================
//Gives Error: base operand of ‘->’ has non-pointer type ‘BaseBond’
void TradingBook::runAnalytics()
{
    for (int i=0; i < bondCount; i++)
    {
        tradingBook[i]->calcPrice(tradingBook[i]->getYield());
        tradingBook[i]->calcDV01();
        tradingBook[i]->calcRisk();

        printf("Bond: %s\n"
               "  Price: %.3f\n"
               "  DV01: %.3f\n"
               "  Risk: %.3f\n", tradingBook[i]->getID(), tradingBook[i]->getPrice(), tradingBook[i]->getDV01(), tradingBook[i]->getRisk());
    }
}

I get the error base operand of ‘->’ has non-pointer type ‘BaseBond’ at every instance of ->, but only in the runAnalytics() method. tradingBook is a public class variable. Why would it give me an error in the bottom method but not the constructor? I don't get it.

I also tried changing all the tradingBook[i]->method() to tradingBook[i].method() in the 2nd method, but it gives me a segmentation fault so I figured that isn't right. Can anyone help me clear up my confusion?

In case it is needed, here is the header file for TradingBook:

class TradingBook
{
    public:
        TradingBook(const char* yieldCurvePath, const char* bondPath);
        double getBenchmarkYield(short bPeriods) const;

        BaseBond* tradingBook;
        int treasuryCount;
        Treasury* yieldCurve;
        int bondCount;
        void runAnalytics();

};

BaseBond is an abstract class. It's children are CouponBond and ZeroCouponBond. tradingBook[i] is filled with both types. Here is the header for BaseBond:

class BaseBond{
  public:
    virtual double getPrice() = 0;
    virtual double getYield() = 0;
    virtual short getPeriods() = 0;
    virtual char* getID() = 0;
    virtual double getDV01() = 0;
    virtual double getRisk() = 0;
    virtual char* getRateType() = 0;
    virtual void calcPrice(double nyield) = 0;
    virtual double calcPriceR(double nyield) const = 0;
    virtual void calcDV01() = 0;
    virtual void calcRisk() = 0;


};

Thank you in advance, stackOverFlow!

Upvotes: 2

Views: 11366

Answers (3)

smci
smci

Reputation: 33970

Dani is correct that you should declare and allocate an array of your base-type with:

BaseBond** tradingBook;
...
tradingBook = new BaseBond[bondCount];

(But if it's variable-sized and you will be appending and removing, you'll either need malloc() (painful) or else use an STL Vector(/whatever) instead of array. For simplicity, allocate the largest array you might reasonably need.)

Anyway, sounds like the compiler (and documentation) tell you 'BaseBond' is an abstract base class which cannot be directly instantiated (but it will have subclasses which can). Figure out which subclasses by reading the documentation or code examples (or link it here if you can't figure that out after reading). Either that or you're supposed to define your own subclass class MyInheritedBond (BaseBond) and implement whatever methods are pure virtual (i.e. whichever methods the compiler nags about):

class MyInheritedBond (BaseBond) {
    void PVfn1() { /* empty dummy implementation to satisfy the compiler */ }
    int  PVfn2(...) { return NULL; }
    ...
};

Upvotes: 1

Daniel
Daniel

Reputation: 31609

It because this:

BaseBond* tradingBook[bondCount];

in the constructor constructs a scoped variable that hides tradingBook. change that whole line to:

tradingBook = new BaseBond*[bondCount];

and the line

BaseBond* tradingBook;

in the header to

BaseBond** tradingBook;

and it should work.

Upvotes: 4

Michael Goldshteyn
Michael Goldshteyn

Reputation: 74470

That's because tradingBook[i] is an object, not a pointer, since you are referring to the member variable tradingBook which is defined as TradingBook *tradingBook. So, use tradingBook[i]. instead of tradingBook[i]-> .

Upvotes: 5

Related Questions