Хранение производных классов в векторе базового класса

#vector #derived-class

#вектор #производный класс

Вопрос:

Я видел несколько версий своего вопроса, но я все еще не могу найти ответ, который работает. Я определил базовый класс с именем TwoPort и два производных класса с именами Reflector и Waveguide следующим образом:

 #include <vector>

class TwoPort
{
public:
    TwoPort() { yeast = ywest = 0.0; }
    ~TwoPort() {}

    double getyeast() { return yeast; }
    double getywest() { return ywest; }

    virtual void step(double xeast, double xwest);

protected:
    double yeast;
    double ywest;
};

class Reflector :
    public TwoPort
{
public:
    Reflector() { Gamma = 0.0; }
    ~Reflector() {}

    void step(double xeast, double xwest) override;

    void setReflection(double G) { Gamma = G; }

private:
    double Gamma;
};

class Waveguide :
    public TwoPort
{
public:
    Waveguide() { oldest = 0; }
    ~Waveguide() {}

    void step(double xeast, double xwest) override;

    void setDelay(unsigned int delay);

private:
    std::vector<double> eastBuffer, westBuffer;
    unsigned int oldest;
};
  

Моя цель — создать вектор, содержащий смесь отражателей и волноводов. Основываясь на ответах на предыдущие вопросы, подобные моим, я перепробовал несколько подходов, но пока ни один из них не сработал. Например:

 int main()
{
    std::vector<std::unique_ptr<TwoPort>> tpcascade;
    
    tpcascade.emplace_back(new Reflector);
    tpcascade.emplace_back(new Waveguide);
    tpcascade.emplace_back(new Reflector);
    tpcascade[0]->setRefection(0.25);
}
  

В этом случае компилятор не распознает метод setReflection. Итак, я попробовал это:

 int main()
{
    std::vector<std::unique_ptr<TwoPort>> tpcascade;
    
    auto ref = std::make_unique<Reflector>();
    ref->setReflection(0.25);
    tpcascade.emplace_back(ref);
}
  

В этом случае я могу установить отражение, но я получаю длинное и сложное сообщение об ошибке в инструкции emplace.

Помогите!

Ответ №1:

Провел некоторое исследование и попробовал вариант второго подхода, описанного выше:

 int main()
{
    std::vector<std::unique_ptr<TwoPort>> tpcascade;
    
    auto ref = std::make_unique<Reflector>();
    ref->setReflection(0.25);
    tpcascade.push_back(std::move(ref));
}
  

Переключение на shared_ptr, похоже, тоже работает и немного чище:

 int main()
{
    std::vector<std::shared_ptr<TwoPort>> tpcascade;

    auto ref = std::make_shared<Reflector>();
    ref->setReflection(0.25);
    tpcascade.push_back(ref);
}
  

Это также, кажется, работает, но мне кажется рискованным:

 tpcascade.push_back(std::make_shared<Reflector>());
std::dynamic_pointer_cast<Reflector>(tpcascade[0])->setReflection(0.25);