在模板的构造函数末尾调用模板的析构函数 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;
}
mu
和 var
的值与 mean
和 variance
的值不同(它们应该是)。当我查看它时,我发现 Matrix
class 的析构函数在 NormalSampler_multi
的构造函数的末尾被调用。所以我猜它删除了mu
和sigma
的值,但我真的不明白为什么以及如何解决它。
矩阵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) {
- 参数 m
和 VarCovar
将在构造函数结束时销毁。
您的问题可能是由于 Matrix
没有遵守 rule of 3/5/0。 mu = m; var = VarCovar;
调用的默认生成的赋值运算符执行成员赋值,这会弄乱您的 class 不变量。你最终得到 mu.pt == m.pt
,然后当 m
被销毁时,mu.pt
是一个悬空指针。
一个简单的解决方案是将 pt
替换为 vector<vector<double>>
,然后您的 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;
}
mu
和 var
的值与 mean
和 variance
的值不同(它们应该是)。当我查看它时,我发现 Matrix
class 的析构函数在 NormalSampler_multi
的构造函数的末尾被调用。所以我猜它删除了mu
和sigma
的值,但我真的不明白为什么以及如何解决它。
矩阵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) {
- 参数 m
和 VarCovar
将在构造函数结束时销毁。
您的问题可能是由于 Matrix
没有遵守 rule of 3/5/0。 mu = m; var = VarCovar;
调用的默认生成的赋值运算符执行成员赋值,这会弄乱您的 class 不变量。你最终得到 mu.pt == m.pt
,然后当 m
被销毁时,mu.pt
是一个悬空指针。
一个简单的解决方案是将 pt
替换为 vector<vector<double>>
,然后您的 class 将符合零规则。或者,您可以实施正确的赋值运算符。
(脚注 - 可能还有其他问题,这只是一个突出的问题)。