【发布时间】:2011-06-29 02:06:56
【问题描述】:
不久前,我在一个网站上发现了一些实用函数的代码示例,这些示例在 creating、destructing 对象,甚至在重载它们的某些 operators 时使用。
更准确地说,主要使用以下成员函数:init、copy、set和destroy。
-
init成员函数用于初始化所有私有成员。它主要在constructors内部调用,例如default或parameter constructor。 -
copy成员函数用于对作为const reference传递的对象执行deep copy。它在reference constructor和operator =的重载中调用。 -
set成员函数,主要是allocates内存供需要的private members使用。 - 最后,
destroy成员函数用于releasing分配的内存。例如,在destructor内部调用它。
我想听听您的意见,并知道这是否是一种好的编程习惯?有哪些好处或坏处?欢迎任何cmets和建议!
下面,我将说明如何为 CMatrix<T> 类定义这些成员函数。
矩阵.h
template < class T >
class CMatrix{
CMatrix(){ this->initMatrix(); }
CMatrix(int nRows, int nCols, int nChannels){
this->initComplexMatrix();
this->setComplexMatrix(nRows, nCols, nChannels);
}
CMatrix(const CMatrix<T> & refMatrix){
this->initComplexMatrix();
this->copyComplexMatrix(refMatrix);
}
CMatrix<T> & operator = (const CMatrix<T> & refMatrix){
if(this!=&refMatrix){
this->destroyComplexMatrix();
this->initComplexMatrix();
this->copyComplexMatrix(refMatrix);
}
return (*this);
}
T & CMatrix<T>::operator()(int, int, int);
T CMatrix<T>::operator()(int, int, int) const;
......
void initMatrix();
void copyMatrix(const CMatrix<T> & );
void setMatrix(int, int, int = 1);
void destroyMatrix();
......
~CMatrix(){ this->destroyMatrix(); }
private:
T *** m_pData;
int m_nRows;
int m_nCols;
int m_nChannels;
};
矩阵.cpp
#include <matrix.h>
template < class T >
inline T & CMatrix<T>::operator()(int mrow, int mcol, int mchannel){
assert(mrow >= 0 && mrow < this->getRows());
assert(mcol >= 0 && mcol < this->getCols());
assert(mchannel >= 0 && mchannel < this->getChannels());
return this->m_pData[mrow][mcol][mchannel];
}
template < class T >
void CMatrix<T>::initMatrix(){
this->m_nRows = 0;
this->m_nCols = 0;
this->m_nChannels= 0;
this->m_pData = NULL;
}
template < class T >
void CMatrix<T>::copyMatrix(const CMatrix<T> & refMatrix){
if(refMatrix.m_pData!=NULL){
this->setMatrix(refMatrix.getRows(), refMatrix.getCols(), refMatrix.getChannels());
for(register int dy=0; dy < this->getRows(); dy++){
for(register int dx=0; dx < this->getCols(); dx++){
for(register int ch=0; ch < this->getChannels(); ch++){
this->m_pData[(dy)][(dx)][(ch)] = refMatrix.m_pData[(dy)][(dx)][(ch)];
}
}
}
}
else{
this->m_pData = NULL;
}
}
template < class T >
void CMatrix<T>::setMatrix(int nRows, int nCols, int nChannels){
this->destroyMatrix();
this->m_pData = NULL;
this->m_pData = new T ** [nRows];
for(register int dy=0; dy < nRows; dy++){
this->m_pData[dy] = NULL;
this->m_pData[dy] = new T * [nCols];
for(register int dx=0; dx < nCols; dx++){
this->m_pData[dy][dx] = NULL;
this->m_pData[dy][dx] = new T[nChannels];
}
}
this->setRows(mrows);
this->setCols(mcols);
this->setChannels(mchannels);
}
template < class T >
void CMatrix<T>::destroyMatrix(){
if(this->m_pData!=NULL){
for(register int dy=0; dy < this->getRows(); dy++){
for(register int dx=0; dx < this->getCols(); dx++){
delete [] this->m_pData[dy][dx];
}
delete [] this->m_pData[dy];
}
delete [] this->m_pData;
this->m_pData = NULL;
}
}
【问题讨论】:
-
从顶层看,对我来说似乎很合乎逻辑
-
如果某些成员是 const 怎么办?然后你需要使用初始化列表。
-
@Sam:如果有任何成员不能默认构造。还要创建父对象的
const实例。 -
另外,模板类通常是defined inline。看起来您的示例会为除了人为示例之外的任何内容产生链接器错误。
-
@Javier:因为成员的类型没有零参数的构造函数?
标签: c++ constructor operator-overloading destructor