在模板的构造函数末尾调用模板的析构函数 class

Destructor of a template called at the end of constructor of a template class

我在使用模板 class 时遇到了一些问题。这是我的 classes 的定义(我只保留了错误来自的基本部分): Sampler.h

#ifndef SAMPLER_H
#define SAMPLER_H

#include "matrix.h"
#include "MatrixOperations.h"

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

const Matrix ZEROS = zeros_mat(1,1);
const Matrix UNIT = unit_mat(1);

class NormalSampler_multi:public Sampler<Matrix>
{
   public:
           virtual Matrix getnumber();
           NormalSampler_multi(Matrix m=ZEROS, Matrix VarCovar=UNIT);
           void printMean();
           void printVar();
   private:
            Matrix mu;
            Matrix var;


};
#endif


和cpp文件: Sampler.cpp

#include "Sampler.h"
#include"matrix.h"
#include "MatrixOperations.h"

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

NormalSampler_multi::NormalSampler_multi(Matrix m, Matrix VarCovar){
    if(m.get_nbColumns()>1 && m.get_nbRows()>1){
        cout << "The mean should be a 1d-matrix\n";
        exit(EXIT_FAILURE);
    }
    if(VarCovar.isSymmetric()==false){
        cout << "The Variance-Covariance matrix should be symmetric\n";
        exit(EXIT_FAILURE);
    }
    mu = m;
    var = VarCovar;
}

void NormalSampler_multi::printMean(){mu.print_matrix();}
void NormalSampler_multi::printVar(){var.print_matrix();}


Matrix NormalSampler_multi::getnumber(){//Not implemented yet};

这是我的问题。当我运行下面的代码: main.cpp

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

#include "matrix.h"
#include "MatrixOperations.h"
#include "Sampler.h"

int main(){

    //Vector of means
    Matrix mean(5,1);
    for(int i=0;i<5;i++){
        mean(i,0) = i;
    }

    //Creation of the multidimensional sampler
    NormalSampler_multi Z(mean, variance);
    cout << "Print of the mean after assignment:" << endl;
    Z.printMean();
    cout << "Print of the variance after assignment" << endl;
    Z.printVar();
    return 0;

}

muvar 的值与 meanvariance 的值不同(它们应该是)。当我查看它时,我发现 Matrix class 的析构函数在 NormalSampler_multi 的构造函数的末尾被调用。所以我猜它删除了musigma的值,但我真的不明白为什么以及如何解决它。

矩阵class的(基本部分)定义如下: Matrix.h

#ifndef MATRIX_H
#define MATRIX_H


class Matrix{
public:
    Matrix(int nbRows=0, int nbColumns=0); 
    Matrix(const Matrix& a); 
    ~Matrix(); 

    //Access to elements
    double& operator()(int i, int j);  

    int get_nbRows(void) const;
    int get_nbColumns(void) const;

    //Useful functions
    void print_matrix(void);

protected:
    int n; //Number of rows
    int p; //Number of columns
    double **pt; //Pointer to elements

};

#endif // MATRIX_H

及其实现: Matrix.cpp

#include "matrix.h"
#include "MatrixOperations.h"
#include <iostream>
#include <cstdlib>
#include <math.h>
#include <cmath>
using namespace std;

Matrix::Matrix(int nbRows, int nbColumns){
    n = nbRows;
    p = nbColumns;
    pt = new double*[n];
    for(int i=0; i<n; i++){
        pt[i] = new double[p];}
    //Initialize the array to 0
    for(int i=0; i<n; i++){
        for(int j=0; j<p; j++){
            pt[i][j] = 0;
        }
    }
}

Matrix::Matrix(const Matrix& a){
    n = a.n;
    p = a.p;
    pt = new double*[n];
    for(int i=0; i<n; i++){
        pt[i] = new double[p];
        for(int j=0; j<p; j++){
            pt[i][j] = a.pt[i][j];
        }
    }

}

Matrix::~Matrix(){
    cout << "destructor called\n";
    delete[] pt;}

int Matrix::get_nbRows(void) const {return n;}
int Matrix::get_nbColumns(void) const {return p;}


double &Matrix::operator()(int i, int j){
    if ((i < 0)||(i>=n)||(j < 0)||(j>=p))
    {
        cout << "Index out of bounds! \n";
        exit(EXIT_FAILURE);
    }
    return pt[i][j];
}

//Print a matrix on the console
void Matrix::print_matrix(void){
    cout << "[";
    for(int i=0; i<n; i++){
            cout << "[";
        for(int j=0; j<p; j++){
            cout << (*this)(i,j);
            if(j<p-1){cout  << ",";}
        }
        cout << "]";
        if(i<n-1){cout << ",\n";}
        else{}
    }
    cout << "]\n";
    cout << endl;
}

谢谢!

NormalSampler_multi(Matrix m, Matrix VarCovar) { - 参数 mVarCovar 将在构造函数结束时销毁。

您的问题可能是由于 Matrix 没有遵守 rule of 3/5/0mu = m; var = VarCovar; 调用的默认生成的赋值运算符执行成员赋值,这会弄乱您的 class 不变量。你最终得到 mu.pt == m.pt,然后当 m 被销毁时,mu.pt 是一个悬空指针。

一个简单的解决方案是将 pt 替换为 vector<vector<double>>,然后您的 class 将符合零规则。或者,您可以实施正确的赋值运算符。

(脚注 - 可能还有其他问题,这只是一个突出的问题)。