0

So, I'm going to do the best job defining my problem, so bear with me please. I am working on a basic finance assignment, wherein I make multiple header files for different base classes: these are Assets, Position, and Portfolio. Assets is my base class, and the Position class includes a reference to an Assets object by forward declaration, and the Portfolio class contains a similar reference to the Position class by forward declaration.

Now, I am trying to create a method in Portfolio called getPortfolioValue that will return the market value of the portfolio's Position object based on whether that object is one of Asset's derived classes, which are Equity, Preferred, and Bond.

Each of these has a getMarketValue method that is called (that actually generates the numerical answer) depending on what their inherited getter, getAssetType, tells me their Asset type is.

getPortfolioValue is defined in Portfolio.hpp, and implemented in Position.hpp (because of forward-declaration), but gives all sorts of "Incomplete Type" errors. The problematic part is on the bottom of the 2nd-to-last code (Position.hpp).

I have tried to give the cleanest possible MWE. Would someone have any idea on how to make this getPortfolioValue method work that has to span >2 header files? Thank you extremely in advance.

Picture of error: Picture of error

Here is my code:

Assets.hpp

#ifndef Assets_hpp
#define Assets_hpp
#include <stdio.h>
#include <fstream>
#include <string>
#include <cmath>

#include "Position.hpp"
#include "Portfolio.hpp"

using namespace std;


class Asset{
private:
    string assetType;
    double currentPrice;
    string securityIssuer;
    string securitySymbol;

public:
    Asset(const string& a = "n/a", const double& b = 0.0, const string& c = "n/a", const string& d = "n/a") :
    assetType(a), currentPrice(b), securityIssuer(c), securitySymbol(d)
    {
    };

    virtual string getAssetType();
    virtual double getMarketValue(const int& n);

    virtual ~Asset() {};

};

class Equity: public Asset{
public:

    Equity(const string& a = "EQUITY", const double& b = 0.0, const string& c = "n/a", const string& d = "n/a") :
    Asset(a, b, c, d) 
    {                       
    }:

    virtual string getAssetType(); //Virtual version of Asset's getAssetType
    virtual double getMarketValue(const int& n);


};

class Preferred: public Equity {
public:
    Preferred(const string& a = "PFD", const double& b = 0.0, const string& c = "n/a", const string& d = "n/a") :
    Equity(a, b, c, d)
    {
    };

    virtual double getMarketValue(const int& n);
};


class bond: public Asset{
private:
    double coupon_rate;
    double coupon_freq;
    double par;

public:
    bond(const string& a = "BOND", const double& b = 0.0, const string& c = "n/a", const string& d = "n/a", double e = 0.0, double f = 0.0, double g = 0.0) :
    Asset(a, b, c, d), coupon_rate(e), coupon_freq(f), par(g)
    {
    };

    double bond_value(int num_bonds);

    virtual string getAssetType(); //Virtual version of Asset's getAssetType
    virtual double getMarketValue(const int& n);

};

#endif /* Assets_hpp */

Assets.cpp

#include "Assets.hpp"

string Asset::getAssetType() {
    return assetType;
}


string Equity::getAssetType() { //Virtual implementation for Equity.
    return "EQUITY";
}


string bond::getAssetType() { //Virtual implementation for bond.
    return "BOND";
}

Position.hpp

#ifndef Position_hpp
#define Position_hpp
#include <stdio.h>
#include <fstream>
#include <cmath>
#include <string>
#include "Portfolio.hpp"

using namespace std;

class Asset;

class Position{
private:
    Asset* base;
    int position_size;
    double cost_basis;
    double position_age;

public:
    Position(Asset* a, const int& b = 0.0, const double& c = 0.0,
             const double& d = 0.0) :
    base(a), position_size(b), cost_basis(c), position_age(d)              
    {                                                                      
    };

    Asset* getAssetBase() { return base;}      //Getter
    void setAssetBase(Asset* b) { base = b;}   //Setter

};

//  ****************PROBLEM RIGHT BELOW HERE********************************

inline double Portfolio::getPortfolioValue(const int& n) {
if (position->getAssetBase()->getAssetType() == "EQUITY") {
    return position->getAssetBase()->getMarketValue(const int& n);
}

else if (position->getAssetBase()->getAssetType() == "PREFERRED") {
    return position->getAssetBase()->getMarketValue(const int& n);
}

else if (position->getAssetBase()->getAssetType() == "BOND"){
    return position->getAssetBase()->getMarketValue(const int& n);
    }
}
#endif /* Position_hpp */

Portfolio.hpp

#ifndef Portfolio_hpp
#define Portfolio_hpp
#include <stdio.h>
#include <fstream>
#include <string>
#include <cmath>

class Position;

class Portfolio {
private:
    Position* position;
    int num_positions;

public:
    Portfolio(Position* a, const int& b) : position(a), num_positions(b)
    {
    };

    Portfolio(const Portfolio&);

    Position* getPosition() { return position;}     //Getter

    double getPortfolioValue(const int& n); //Both of these implemented in Position header.
    double PortolioCostBasis();


};

#endif /* Portfolio_hpp */
Coolio2654
  • 1,589
  • 3
  • 21
  • 46
  • 2
    why are you having those if statements the point of a inheritance is to avoid that. – Jake Freeman Dec 03 '17 at 22:07
  • Those if statements may indeed be unnecessary, I'm not sure how else I would do it though. The return-> ... code bits also return the same error, even if I got rid of the if statements somehow. – Coolio2654 Dec 03 '17 at 22:12
  • Your includes look strange. "Assets.hpp" has no dependencies on "Position.hpp" and "Portfolio.hpp" so these should be removed. Also the `Position` class has no dependencies on `Portfolio`, so the include should be removed from "Position.hpp". Put the definition of `Portfolio::getPortfolioValue()` into "Portfolio.hpp" where it belongs. In "Portfolio.hpp" only include "Position.hpp", the only dependency it has. – zett42 Dec 03 '17 at 22:26
  • On a side note, `using namespace std;` is bad practice, [using it in a header file is just completely wrong](https://stackoverflow.com/a/14575955/7571258). – zett42 Dec 03 '17 at 22:34
  • @zett42 I took the advice of the top answer here when using the forward declarations, if you want my reasoning. https://stackoverflow.com/questions/8526819/c-header-files-including-each-other-mutually I hope that helps. – Coolio2654 Dec 03 '17 at 22:48
  • The basic idea is right, but your includes are still wrong. I've added a more detailed answer. – zett42 Dec 03 '17 at 23:23

3 Answers3

1

Your includes are not based on the dependencies of the classes, that's where the main issues come from.

From "Assets.hpp" remove these lines, because the classes Asset, Equity, Preferred and bond do not depend on Position and Portfolio:

#include "Position.hpp"
#include "Portfolio.hpp"

There is a syntax error here (remove ":" and also obsolete ";" after similiar functions):

Asset(a, b, c, d) 
{                       
}:

Remove this line from "Position.hpp", because Position does not depend on Portfolio:

#include "Portfolio.hpp"

Also move the definition of Portfolio::getPortfolioValue into "Portfolio.hpp" where it belongs:

class Portfolio {
public:
    double getPortfolioValue(const int& n) {
        if (position->getAssetBase()->getAssetType() == "EQUITY") {
            return position->getAssetBase()->getMarketValue(const int& n);
        }

        else if (position->getAssetBase()->getAssetType() == "PREFERRED") {
            return position->getAssetBase()->getMarketValue(const int& n);
        }

        else if (position->getAssetBase()->getAssetType() == "BOND"){
            return position->getAssetBase()->getMarketValue(const int& n);
        }
    }
    /* other stuff omitted for brevity */
};

Now your Portfolio class depends on Position and Asset, so you must include their headers in "Portfolio.hpp":

#include "Position.hpp"
#include "Assets.hpp"

Also remove the forward declaration from "Portfolio.hpp":

class Position;

As you are calling methods of Position, the forward declaration is of no use. You need the full declaration.

That should fix the compile errors.

It's still strange why you have these ifs in getPortfolioValue(). You are doing the same in all of these branches...

zett42
  • 25,437
  • 3
  • 35
  • 72
  • I've taken your advice (yeah, my if statements were also needless), and implemented it, but now I have an even weirder error. https://imgur.com/a/pSvHV What does this mean? – Coolio2654 Dec 04 '17 at 14:41
  • @Coolio2654 You have not implemented `getMarketValue()` yet. – zett42 Dec 04 '17 at 15:03
  • Your advice helped me resolve this issue very well. I can see that I tripped myself up over forward declarations when in fact they were not adequate, and using workarounds to get them to work added further error-prone complexity to my already sizable code. Thanks for pointing out my simple error. – Coolio2654 Dec 05 '17 at 21:59
0

The problem is you need to do if(position->getAssetBase()->getAssetType() == "Equity") instead of if(position->getAssetBase()->getAssetType()= "Equity").

Hope this helps.

Jake Freeman
  • 1,700
  • 1
  • 8
  • 15
0

The inline methods that demonstrate the problem depend on the definitions from asset.h but you have not included asset.h at the time you define the problem functions. I'm not sure if merely including asset.h before the problem functions would fix the issue or not (there may be circular dependencies here that I'm not seeing).

SoronelHaetir
  • 14,104
  • 1
  • 12
  • 23
  • I include'd both of the latter headers in my Assets header at the top, and forward declared the necessary classes in both of the latter ones. I know this method works for simple forward-declarations, but seems not to for my more complicated use of it. – Coolio2654 Dec 03 '17 at 22:10