Получение адреса «внутренних» классов класса - PullRequest
0 голосов
/ 29 мая 2020

У меня есть виртуальный базовый класс ValuationFunction, который в основном просто содержит параметры и может выводить значение на основе некоторых вычислений. Все производные классы ведут себя в основном одинаково, за исключением одного, который называется FunctionCombiner и выглядит следующим образом:

class FunctionCombiner : public valuationFunction
{
public:
    FunctionCombiner(std::vector<std::shared_ptr<valuationFunction>>& Inner_);
    void ValueInstrument();
    void RiskFactorAdd(double increment, RiskFactor simulatedRiskFactor);
    void RiskFactorMultiply(double factor, RiskFactor simulatedRiskFactor);
    virtual valuationFunction* clone() const;
private:
    std::vector<std::shared_ptr<valuationFunction>> Inner;
};

Принцип его работы заключается в том, что он содержит вектор указателей на другие производные классы функции оценки. и для каждой из его функций он в основном передает инструкции каждому из внутренних классов, которые он содержит, вместо того, чтобы выполнять какие-либо операции самостоятельно. Теперь моя проблема в том, что я хочу сравнить свои классы valuationFunction, чтобы увидеть, одинаковы ли они в какой-то момент, для всех производных классов, кроме FunctionCombiner, я могу просто напрямую сравнить указатели, но для FunctionCombiner мне, конечно, нужны указатели на внутренние объекты, а не только указатель на FunctionCombiner, это все, с чем, как мне кажется, приходится работать. Как лучше всего получить адреса внутренних классов?

Я пробовал создать виртуальную функцию, которая возвращает вектор внутренних указателей (или саму себя), а затем скомпилировать все эти векторы вместе, чтобы сравнить их, но в большинстве случаев это не компилируется, случайно копируется. , создал много кода, в котором я повторяю себя и был запутан. Моя следующая идея (которую я не хочу делать) - просто добавить параметр ко всем моим классам с уникальным идентификатором, который я затем извлечу и использую для сравнения вместо адресов, на которые указывают интеллектуальные указатели. Это решение определенно не выглядит очень элегантным, и я надеюсь, что смогу сделать это как-нибудь иначе.

EDIT с дополнительным объяснением: проблема в том, что если у меня есть FunctionCombiner, который содержит функцию A и функцию B, и я сравниваю это с функцией A, они, конечно, не будут равны. Когда я сравниваю функцию A с FunctionCombiner, я действительно хочу сравнить функцию A с функцией A (внутри объединителя функций) и функцию A с функцией B (внутри объединителя функций). Конечной целью было бы исключить дубликаты, чтобы после сравнения функции A и FunctionCombiner я мог удалить одну из дублирующих функций A.

Не думаю, что это действительно нужно, но valuationFunciton ниже:

class valuationFunction
{
public:
    valuationFunction(double TTM);
    virtual void ValueInstrument() = 0;
    virtual double GetValue() const;
    virtual void RiskFactorAdd(double increment, RiskFactor simulatedRiskFactor) = 0;
    virtual void RiskFactorMultiply(double factor, RiskFactor simulatedRiskFactor) = 0;
    virtual void UpdateTTM(double timeStep);
    virtual valuationFunction* clone() const = 0;
    virtual ~valuationFunction() {}
private:

protected:
    double f;
    double TTM;
};

1 Ответ

1 голос
/ 30 мая 2020

Если я вас правильно понял, вы хотите сравнить общие указатели, чтобы увидеть, содержат ли они один и тот же сохраненный указатель? Тогда это тривиально: просто используйте == operator.

Внутренне operator== для std::shared_ptr реализуется как:

lhs.get() == rhs.get()

т.е. проверяет сохраненные указатели одинаковы.

Демо


Что вы можете сделать, так это использовать std::find() для поиска определенного std::shared_ptr<valuationFunction> в вашем векторе «внутреннего» объекты. Также есть функция end() в FunctionCombiner, которую вы можете сравнить с предыдущим концом векторного итератора.

Итак, определение вашего класса будет примерно таким:

class FunctionCombiner : public ValuationFunction
{
public:
    typedef std::vector<std::shared_ptr<ValuationFunction>>::iterator iterator;

    FunctionCombiner(std::vector<std::shared_ptr<ValuationFunction>> Inner_) : Inner(std::move(Inner_)) {}
    virtual ~FunctionCombiner() = default;

    iterator FindValuationFunction(const std::shared_ptr<ValuationFunction>& fn) {
        return std::find(Inner.begin(), Inner.end(), fn);
    }

    iterator end() { return Inner.end(); }

private:
    std::vector<std::shared_ptr<ValuationFunction>> Inner;
};

Тогда вы просто нужно позвонить по FindValuationFunction() и сравнить с end(). Если FindValuationFunction() не равно end(), общий указатель существует в векторе внутренних объектов.

Я также изменил конструктор, чтобы он принимал вектор по значению и перемещал его в Inner. Так будет эффективнее.

Демо .

Надеюсь, это то, что вы ищете.

...