我声明,我是一个C程序员不是一个C ++程序员更多的(与C ++我是个初学者:P)
我已经写了一个C ++类来管理多维阵列(n维矩阵)。 这个类有方法来创建矩阵和设置,并获得价值/从基体(也设置里面的位置)。
我有两个问题:
有了,我想类似米语法的想法(X,Y,Z,...,n)的设置/获取值的一些方法使用省略号EG:的getValue(INT DIM0,...); 但我认为这是危险的; 虽然我写我假定传递的参数是相同数量的矩阵的各个维度的功能,用户可能超过必要使更少的数值,那么他将没有编译器错误或警告。
我想能够管理,矩阵细胞矩阵在创建时运行期间包含(不使用工会并以某种方式宣布型)的数据类型。 在类代码中,我插一个typedef(用于开发目的),它指明了这样的修改会/可能会影响点。
对于第一个问题,我没有想法比实现要好。 你有什么建议?
为了解决第二个问题,我可能想为方法创建的getValue)重载(,的setValue()和createMatrix(),但这个想法需要一些变通方法,并可能完全重写每一个单一的方法,然后有更多的副本“同样的”代码(我想避免的意图有更好的维修能力),而且这种解决方案并不授予管理所有可能的类型。 我正在考虑使用模板,但如果这种方式是更好的办法,我不明白。 你有什么建议?
这些都是进行修改,以解决这两个问题的方法主要有:
在CPP模块的方法:
int Matrix::createMatrix(Matrix::value_t *values)
{
int retval=1;
if ( (m_values!=NULL || !numOfDim()) && valAreIntAlloc()==true ) {
return 0;
}
if (values!=NULL) {
m_values=values;
setValAreIntAlloc(false);
} else {
setValAreIntAlloc(true);
// Compute the number of elements for
// the whole matrix
for(int i=0;i<numOfDim();i++) {
retval*=numOfElemInDim(i);
if (!retval) {
//Indicate that a dimension has a 0 value
//as numOfElemInDim! The caller will be allowed
//to know the such a dimension using: -retval-1;
retval=-(i+1);
break;
}
}
if (retval>0) {
m_values=new value_t[retval];
if (m_values!=NULL)
retval=0;
}
}
//Returns:
//1 if values is an external allocated memory,
//0 if nothing has been allocated or the
//m_values is already set as internal!
//elsewhere the number of allocated elements.
return retval;
}
void Matrix::setPositions(int dim0, ...)
{
va_list vl;
va_start(vl,dim0);
setPosition(0,dim0);
for (int i=1;i<numOfDim();i++)
setPosition(i,va_arg(vl,int));
va_end(vl);
}
Matrix::value_t Matrix::getValue(int dim0, ...)
{
va_list vl;
va_start(vl,dim0);
setPosition(0,dim0);
for (int i=1;i<numOfDim();i++)
setPosition(i,va_arg(vl,int));
va_end(vl);
return getValue();
}
void Matrix::setValue(Matrix::value_t value, int dim0, ...)
{
va_list vl;
va_start(vl,dim0);
setPosition(0,dim0);
for (int i=1;i<numOfDim();i++)
setPosition(i,va_arg(vl,int));
va_end(vl);
setValue(value);
}
方法内联在头文件中:
inline value_t getValue() { return m_values[posInValueVector()]; }
inline void setValue(value_t value) { m_values[posInValueVector()]=value; }
所述方法的setPosition(),setPositions()用于设置要被管理的所述基质细胞的坐标; 该方法posInValueVector()计算向量使用的坐标的矩阵单元的(通过该方法createMatrix创建)内的索引。
这里人的代码:
main.cpp中
#include <iostream>
#include <cstdio>
#include "matrix.h"
using namespace std;
int main()
{
Matrix m(3);
m.setNumOfElemInDims(4,5,6);
m.createMatrix();
for(int i=0;i<m.numOfElemInDim(0);i++)
for(int j=0;j<m.numOfElemInDim(1);j++)
for(int k=0;k<m.numOfElemInDim(2);k++)
m.setValue(i*100+j*10+k,i,j,k); // matrix(i,j,k)=i*100+j*10+k
//printout the values of all matrix(i,j,k) cells
//I've used the printf because I find it very simple!
for(int i=0;i<m.numOfElemInDim(0);i++)
for(int j=0;j<m.numOfElemInDim(1);j++)
for(int k=0;k<m.numOfElemInDim(2);k++)
printf("(%d,%d,%d)=%03.0f\n",i,j,k,m.getValue(i,j,k));
}
matrix.h
#ifndef MATRIX_H
#define MATRIX_H
class Matrix
{
public:
typedef double value_t;
Matrix();
Matrix(int numOfDim, int *nelem=NULL);
~Matrix();
inline unsigned int numOfDim() const {return m_numOfDim;}
int setNumOfDim(int numOfDim, int *nelem=NULL);
inline int numOfElemInDim(int dim) const
{return (dim<numOfDim())?m_numOfElemInDim[dim]:-1; }
int setNumOfElemInDim(int dim, int nelem);
int setNumOfElemInDims(int el0, ...);
int createMatrix(value_t *values);
inline int createMatrix() { return createMatrix(NULL); }
inline bool valAreIntAlloc() const {return m_valAreIntAlloc;}
inline void setValAreIntAlloc(bool valAreIntAlloc)
{m_valAreIntAlloc = valAreIntAlloc;}
inline int position(int dim) const {return m_positions[dim];}
inline void setPosition(int dim,int value)
{m_positions[dim] = value;}
inline void setPositions(int *positions)
{for(int i=0;i<numOfDim();i++) setPosition(i,positions[i]);}
void setPositions(int dim0, ...);
inline value_t getValue() { return m_values[posInValueVector()]; }
value_t getValue(int dim0, ...);
inline void setValue(value_t value) { m_values[posInValueVector()]=value; }
void setValue(value_t value, int dim0, ...);
private:
int m_numOfDim;
int * m_numOfElemInDim;
int * m_positions;
value_t * m_values;
bool m_valAreIntAlloc;
int posInValueVector();
};
#endif // MATRIX_H
matrix.cpp
#include <iostream>
#include <cstdarg>
#include "matrix.h"
#define __INIT__(v)\
m_numOfDim(v),\
m_numOfElemInDim(NULL),\
m_positions(NULL),\
m_values(NULL),\
m_valAreIntAlloc(false)
Matrix::Matrix():
__INIT__(0)
{
}
Matrix::~Matrix()
{
if (m_numOfElemInDim!=NULL)
delete m_numOfElemInDim;
if (m_positions!=NULL)
delete m_positions;
if (valAreIntAlloc() && m_values!=NULL)
delete m_values;
}
Matrix::Matrix(int numOfDim, int *nelem):
__INIT__(numOfDim)
{
setNumOfDim(numOfDim,nelem);
}
int Matrix::setNumOfDim(int numOfDim, int *nelem)
{
int retval=0;
m_numOfDim = numOfDim;
m_numOfElemInDim = new int[numOfDim];
if (m_numOfElemInDim==NULL)
return 1;
m_positions = new int[numOfDim];
if (m_positions==NULL)
return 2;
for(int i=0;i<m_numOfDim;i++) {
if (setNumOfElemInDim(i,(nelem==NULL)?0:nelem[i])) {
retval=-1;
break;
}
setPosition(i,0);
}
return retval; //All ok!
}
int Matrix::setNumOfElemInDim(int dim,int nelem)
{
int retval=-1;
if (dim<numOfDim()) {
m_numOfElemInDim[dim] = nelem;
retval=0;
}
return retval;
}
int Matrix::setNumOfElemInDims(int el0, ...)
{
va_list vl;
va_start(vl,el0);
setNumOfElemInDim(0,el0);
for (int i=1;i<numOfDim();i++)
setNumOfElemInDim(i,va_arg(vl,int));
va_end(vl);
return 0;
}
int Matrix::createMatrix(Matrix::value_t *values)
{
int retval=1;
if ( (m_values!=NULL || !numOfDim()) && valAreIntAlloc()==true ) {
return 0;
}
if (values!=NULL) {
m_values=values;
setValAreIntAlloc(false);
} else {
setValAreIntAlloc(true);
// Compute the number of elements for
// the whole matrix
for(int i=0;i<numOfDim();i++) {
retval*=numOfElemInDim(i);
if (!retval) {
//Indicate that a dimension has a 0 value
//as numOfElemInDim! The caller will be allowed
//to know the such a dimension using: -retval-1;
retval=-(i+1);
break;
}
}
if (retval>0) {
m_values=new value_t[retval];
if (m_values!=NULL)
retval=0;
}
}
//Returns:
//1 if values is an external allocated memory,
//0 if nothing has been allocated or the
//m_values is already set as internal!
//elsewhere the number of allocated elements.
return retval;
}
void Matrix::setPositions(int dim0, ...)
{
va_list vl;
va_start(vl,dim0);
setPosition(0,dim0);
for (int i=1;i<numOfDim();i++)
setPosition(i,va_arg(vl,int));
va_end(vl);
}
Matrix::value_t Matrix::getValue(int dim0, ...)
{
va_list vl;
va_start(vl,dim0);
setPosition(0,dim0);
for (int i=1;i<numOfDim();i++)
setPosition(i,va_arg(vl,int));
va_end(vl);
return getValue();
}
void Matrix::setValue(Matrix::value_t value, int dim0, ...)
{
va_list vl;
va_start(vl,dim0);
setPosition(0,dim0);
for (int i=1;i<numOfDim();i++)
setPosition(i,va_arg(vl,int));
va_end(vl);
setValue(value);
}
int Matrix::posInValueVector()
{
int pos=position(0);
for(int i=1;i<numOfDim();i++)
pos=pos*numOfElemInDim(i)+position(i);
return pos;
}