实现利用多个其他非继承 classes 的 C++ class 方法?

Implement C++ class method that draws on multiple other non-inherited classes?

所以,我将尽最大努力定义我的问题,所以请多多包涵。我正在做一项基本的财务任务,其中我为不同的基础 classes 制作了多个头文件:它们是 AssetsPositionPortfolioAssets 是我的基础 class,Position class 通过前向声明包含对 Assets 对象的引用,而 Portfolio class 通过前向声明包含对 Position class 的类似引用。

现在,我正在尝试在 Portfolio 中创建一个名为 getPortfolioValue 的方法,该方法将 return 投资组合的 Position 对象的市场价值基于该对象是否是 Asset 的派生对象之一 classes,它们是 EquityPreferredBond.

其中每个都有一个 getMarketValue 方法,该方法被调用(实际上生成数字答案),具体取决于它们继承的 getter、getAssetType,告诉我它们的资产类型是.

getPortfolioValue 在 Portfolio.hpp 中定义,并在 Position.hpp 中实现(由于前向声明),但给出了各种 "Incomplete Type" 错误。有问题的部分在倒数第二个代码的底部(Position.hpp)。

我已尝试提供尽可能干净的 MWE。有人知道如何使这个必须跨越 >2 个头文件的 getPortfolioValue 方法起作用吗?非常感谢您。

错误图片:

这是我的代码:

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 */

问题是您需要 if(position->getAssetBase()->getAssetType() == "Equity") 而不是 if(position->getAssetBase()->getAssetType()= "Equity")

希望对您有所帮助。

演示问题的内联方法取决于 asset.h 中的定义,但您在定义问题函数时未包含 asset.h。我不确定是否仅在问题函数之前包含 asset.h 就可以解决问题(这里可能存在我没有看到的循环依赖关系)。

您的包含不是基于 classes 的依赖项,这是主要问题的来源。

"Assets.hpp" 删除这些行,因为 class 是 AssetEquityPreferredbond 不依赖于 PositionPortfolio:

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

这里有一个语法错误(去掉“:”,也去掉类似函数后的“;”):

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

"Position.hpp"中删除这一行,因为Position不依赖于Portfolio:

#include "Portfolio.hpp"

也把Portfolio::getPortfolioValue的定义移到"Portfolio.hpp"所属的地方:

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 */
};

现在你的 Portfolio class 依赖于 PositionAsset,所以你必须在 "Portfolio.hpp":

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

同时删除 "Portfolio.hpp" 中的前向声明:

class Position;

因为你调用的是Position的方法,前向声明是没有用的。您需要完整的声明。

这应该可以修复编译错误。

为什么在 getPortfolioValue() 中有这些 if 仍然很奇怪。您在所有这些分支中都在做同样的事情...