【问题标题】:Return pointer to array virtual template function返回指向数组虚拟模板函数的指针
【发布时间】:2020-07-22 04:30:54
【问题描述】:

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

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++ templates inheritance virtual


    【解决方案1】:

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

    【讨论】:

    • 感谢您的帮助!当时的想法是不要使用std::vector(因为我是学c++的,所以想从基础开始),所以我将指针作为函数的参数传递。
    • 如果您不能使用std::vector,请创建一次您自己的简化版本。您可以独立于其他代码对其进行测试,反之亦然。
    猜你喜欢
    • 2011-01-12
    • 1970-01-01
    • 1970-01-01
    • 2021-06-25
    • 1970-01-01
    • 1970-01-01
    • 2013-04-10
    • 2023-03-24
    • 1970-01-01
    相关资源
    最近更新 更多