Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 3981080
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 20, 20262026-05-20T05:22:03+00:00 2026-05-20T05:22:03+00:00

A while ago, I found in a website some code examples of utility functions

  • 0

A while ago, I found in a website some code examples of utility functions that are used when creating, destructing objects, or even when overloading some of their operators.
More precisely, the following member functions are mainly used: init, copy, set, and destroy.

  • The init member function is used to initialize all the private members. It’s mostly called inside the constructors, e.g. the default or parameter constructor.
  • The copy member function is used to do a deep copy of an object passed as a const reference. It is called inside the reference constructor and the overload of the operator =.
  • The set member function which mainly allocates memory for the private members that require it.
  • Finally, the destroy member function is used for releasing the allocated memory. It’s called, for example, inside of the destructor.

I would like to have your opinion and know if this is a good programming practice? Which are the benefits or drawbacks? Any comments and suggestions are welcomed!
Below, I’m illustrating how those member functions are defined for a CMatrix<T> class.

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

matrix.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;
    } 
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-20T05:22:04+00:00Added an answer on May 20, 2026 at 5:22 am

    No, this is not recommended. The way you propose is not exception safe and is not compatible with const or subobjects that need non-default construction.

    Instead use the ctor-initializer-list. Code reuse can be achieved through static helper functions called in the ctor-initializer-list or by moving logic into subobject constructors.

    For memory allocation, use a subobject per resource. The memory management logic ends up in the subobject constructor and destructor. In many cases, you can use existing RAII classes from the library, such as std::vector, and not need to write any memory management code yourself.

    Most operators can reuse the logic in the constructors, using the copy-and-swap idiom.

    EDIT: Exception-safe construction might look something like this:

    #include <vector>
    template<typename T>
    class matrix
    {
        int m_nCols;
        std::vector<T*> m_rows;
        std::vector<T> m_cells;
        size_t makeIndex( int row, int col ) const { return row*m_nCols + col; }
    
    public:    
        matrix( int nRows, int nCols )
            : m_nCols(nCols), m_rows(nRows), m_cells(nRows * nCols)
        {
            while (nRows--) m_rows[nRows] = &m_cells[nRows * nCols];
        }
    
        matrix( const matrix<T>& other )
            : m_nCols(other.m_nCols), m_rows(other.m_rows.size()), m_cells(other.m_cells)
        {
            int nRows = other.m_rows.size();
            while (nRows--) m_rows[nRows] = &m_cells[nRows * nCols];
        }
    
        void swap( matrix& other )
        {
            using std::swap;
            swap(m_nCols, other.m_nCols);
            swap(m_rows, other.m_rows);
            swap(m_cells, other.m_cells);
        }
    
        matrix& operator=( matrix other )
        {
            other.swap(*this);
            return *this;
        }
    
        const T& operator()( int row, int col ) const { return m_cells[makeIndex(row,col)]; }
        T& operator()( int row, int col ) { return m_cells[makeIndex(row,col)]; }
    };
    

    The std::vector destructor will take care of freeing the memory, and since the two allocations are separate objects, if m_cells fails to allocate its memory, the destructor for m_rows will run and nothing will leak.

    Of course, std::vector is a little bit overkill here, a fixed-size array RAII class would be sufficient. But std::auto_ptr can’t be used with arrays. I think C++0x is supposed to add a standard fixed-size RAII array class.

    EDIT: Per request, a 3-D version:

    #include <vector>
    template<typename T>
    class cube
    {
        int m_nCols, m_nRows;
        std::vector<T> m_cells;
        size_t makeIndex( int row, int col, int channel ) const { return (channel*m_nRows + row)*m_nCols + col; }
    
    public:    
        cube( int nRows, int nCols, int nChannels )
            : m_nCols(nCols), m_nRows(nRows), m_cells(nRows * nCols * nChannels)
        {
        }
    
        cube( const cube<T>& other )
            : m_nCols(other.m_nCols), m_nRows(other.m_nRows), m_cells(other.m_cells)
        {
        }
    
        void swap( cube& other )
        {
            using std::swap;
            swap(m_nCols, other.m_nCols);
            swap(m_nRows, other.m_nRows);
            swap(m_cells, other.m_cells);
        }
    
        cube& operator=( cube other )
        {
            other.swap(*this);
            return *this;
        }
    
        const T& operator()( int row, int col, int channel ) const { return m_cells[makeIndex(row,col,channel)]; }
        T& operator()( int row, int col, int channel ) { return m_cells[makeIndex(row,col,channel)]; }
    
        class channel_iterator
        {
            cube& const cube;
            int const row, col;
            int channel;
            friend class cube;
            channel_iterator( cube& all, int r, int c, int n ) : cube(all), row(r), col(c), channel(n) {}
        public:
            T& operator*() const { return cube(row, col, channel); }
            channel_iterator& operator++() { ++channel; return *this; }
            channel_iterator operator++(int) { return channel_iterator(cube, row, col, channel++); }
            bool operator!=(const channel_iterator& other) const { assert(&cube == &other.cube); return (row == other.row && col == other.col && channel == other.channel); }
        };
    
        int channel_count() const { return m_cells.size() / m_nRows / m_nChannels; }
        pair<channel_iterator, channel_iterator> range(int row, int col) { return make_pair(channel_iterator(*this, row, col, 0), channel_iterator(*this, row, col, channel_count())); }
    };
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

A while ago, I came across some code that marked a data member of
A while ago I found out that FOP doesn't allow you to use floats,
A while ago, I wrote some Word interop examples in Visual Studio beta 1,
A while ago I had a query that I ran quite a lot for
A while ago another question referred to the (possibly urban tale) statistic that ...
A while ago I had to upgrade some servers from Python 2.4 to Python
A while ago I was poking around with SQLite, trying to port some of
A while ago, I started on a project where I designed a html-esque XML
A while ago I read the Mocks Aren't Stubs article by Martin Fowler and
A while ago, I had a discussion with a colleague about how to insert

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.