Возврат указателя на функцию виртуального шаблона массива - PullRequest
0 голосов
/ 09 апреля 2020

Я хотел бы вернуть массив указателю в виртуальной функции, которая является членом производного класса шаблонного класса. Подробно, мое определение классов:

Sampler.h

#ifndef SAMPLER_H
#define SAMPLER_H

template <class T>
class Sampler
{
      public:
             virtual T getnumber()=0;
             virtual T* simulation(int n)=0;
};

class UniformSampler:public Sampler<double>
{
      public:
              virtual double getnumber();
              virtual double* simulation(int n);
              UniformSampler(double a=0.0, double b=1.0);

      private:
              double low_bound;
              double up_bound;
};
#endif

Класс Sampler - это шаблонный класс для того, чтобы позже можно было получить другой сэмплер с векторами. Реализация такова: Sampler.cpp

#include "Sampler.h"

#include<iostream>
#include<cstdlib>
#include<cmath>
using namespace std;

//Uniform
UniformSampler::UniformSampler(double a, double b)
{
    low_bound=a;
    up_bound=b;
}

double UniformSampler::getnumber()
{
       int myrand=rand();
       while((myrand==0)||(myrand==RAND_MAX)){myrand = rand(); } //We want a number in (0, RAND_MAX).

       double myuni = myrand/static_cast<double>(RAND_MAX); //Create a number in (0,1).
       return low_bound + myuni*(up_bound-low_bound);
}

double* UniformSampler::simulation(int n){
    double simulations[n];
    for(int i=0; i<n; i++){
        simulations[i] = this->getnumber();
    }
    return simulations;
}

Моя проблема в том, что когда я пытаюсь вызвать эту программу в main(), похоже, что присвоение указателя не работает. Вот мой main.cpp:

#include <iostream>
#include <math.h>
#include <cstdlib>
#include <time.h>
using namespace std;

#include "Sampler.h"

int main(){
    srand(time(0));

    int n=10;
    double *unif = new double[n];
    UniformSampler uni;
    unif = uni.simulation(n);
    for ( int i = 0; i < n; i++ ) {
      cout << "*(p + " << i << ") : ";
      cout << *(unif + i) << endl;
    }
    delete[] unif;

    return 0;

}

Когда я запускаю его, он не печатает ни один из элементов, на которые указывает unif. Я не понимаю, что там не так.

1 Ответ

0 голосов
/ 09 апреля 2020

UniformSampler::simulation дважды неверно:

  • double simulations[n]; использует расширение VLA, поэтому не соответствует стандарту C ++.
  • вы возвращаете указатель на локальную переменную, поэтому висячий указатель.

Решение: используйте std::vector вместо.

#include <vector>

template <class T>
class Sampler
{
public:
    virtual ~Sampler() = default;
    virtual T getnumber() = 0;
    virtual std::vector<T> simulation(int n) = 0;
};

class UniformSampler:public Sampler<double>
{
public:
    explicit UniformSampler(double a=0.0, double b=1.0);

    double getnumber() overrid;
    std::vector<double> simulation(int n) override
    {
        std::vector<double> res(n);
        for (auto& val : res){
            res = getnumber();
        }
        return res;
    }
private:
    double low_bound;
    double up_bound;
};

int main(){
    srand(time(0));

    constexpr int n = 10;
    UniformSampler uni;
    auto unif = uni.simulation(n);
    for (int i = 0; i < n; i++ ) {
        std::cout << "p[" << i << "]: " << unif[i] << endl;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...