首页 > 解决方案 > 返回指向数组虚拟模板函数的指针

问题描述

我想在作为模板类的派生类成员的虚函数中将数组返回给指针。详细地说,我的类定义是:

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指向的元素。我不明白那里有什么问题。

标签: c++templatesinheritancevirtual

解决方案


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

推荐阅读