overloading operator()

M

Mohammad

I'm implementing a c++ template class CScan to minipulate a series of
numbers.
I have implemented operator() to select a range of numbers it works
fine for an expression like:
scan1 = scan2(0, 99);

However, I have problem when I try something like:

scan1(0, 99) = scan2(100, 199);

In this case, a temporary object is created and destoryed without
copying the values to scan1. How can I accomplish this? Following is
some of the relavent code.


template<class T>
class CScan
{
public:
CScan() : m_nSize(0), m_pData(NULL)
{
}

CScan(ULONG nSize) : m_nSize(nSize)
{
m_pData = new T[m_nSize];
ZeroMemory(m_pData, m_nSize * sizeof(T));
}

CScan(T* pData, ULONG nSize) : m_nSize(nSize)
{
m_pData = new T[m_nSize];
CopyMemory(m_pData, pData, m_nSize * sizeof(T));
}

CScan(CScan& scan) : m_nSize(scan.m_nSize)
{
m_pData = new T[m_nSize];
CopyMemory(m_pData, scan.m_pData, m_nSize * sizeof(T));
}

~CScan()
{
delete [] m_pData;
}

CScan& operator=(CScan& scan)
{
if (&scan == this)
{
return *this;
}
m_nSize = scan.m_nSize;
delete [] m_pData;
m_pData = new T[m_nSize];
CopyMemory(m_pData, scan.m_pData, m_nSize * sizeof(T));
return *this;
}

ULONG Size()
{
return m_nSize;
}

T& operator[](const ULONG nIndex)
{
if (nIndex >= m_nSize)
{
throw CScanError::OutsideBounds(m_nSize, nIndex);
}
return m_pData[nIndex];
}

const T& operator[](const ULONG nIndex) const
{
if (nIndex >= m_nSize)
{
throw CScanError::OutsideBounds(m_nSize, nIndex);
}
return m_pData[nIndex];
}

CScan operator()(const ULONG nFrom, const ULONG nTo) const
{
if (nFrom >= m_nSize)
{
throw CScanError::OutsideBounds(m_nSize, nFrom);
}
if (nTo >= m_nSize)
{
throw CScanError::OutsideBounds(m_nSize, nTo);
}
ULONG nSize = nTo - nFrom + 1;

if (nSize > 0)
{
return CScan(&m_pData[nFrom], nSize);
}
else
{
return CScan;
}
}

private:
T* m_pData;
ULONG m_nSize;
};
 
R

Ron Natalie

Mohammad said:
I'm implementing a c++ template class CScan to minipulate a series of
numbers.
I have implemented operator() to select a range of numbers it works
fine for an expression like:
scan1 = scan2(0, 99);

However, I have problem when I try something like:

scan1(0, 99) = scan2(100, 199);

In this case, a temporary object is created and destoryed without
copying the values to scan1. How can I accomplish this? Following is
some of the relavent code.

The trick is obviously not to use a temporary copy. The trick would to
have Scan::eek:perator() not return a Scan directly, but an helper class that
would have a pointer/reference to the object that operator() was invoked
on and forward the copy/assignemnts to it (possibly remapping the indices).
 
M

Mohammad

Ron Natalie said:
The trick is obviously not to use a temporary copy. The trick would to
have Scan::eek:perator() not return a Scan directly, but an helper class that
would have a pointer/reference to the object that operator() was invoked
on and forward the copy/assignemnts to it (possibly remapping the indices).

I tried this approach but having compiling problems. It seems that
VC++ 6.0 does not support return value overloading. Are there any
other ways? It is at all possible to do something like that in C++.
 
R

Ron Natalie

Mohammad said:
"Ron Natalie" <[email protected]> wrote in message news:<[email protected]>...
I tried this approach but having compiling problems. It seems that
VC++ 6.0 does not support return value overloading. Are there any
other ways? It is at all possible to do something like that in C++.

I dont' know that means. There's no such thing as return value overloading,
nor is one necessary to do what I suggested.
 
M

Mohammad

Ron Natalie said:
I dont' know that means. There's no such thing as return value overloading,
nor is one necessary to do what I suggested.

Sincere thaks for your help! My confusion was partly due to some
problem with VC++ 6.0. My code compiled and work perfectly when I used
VC++ 7.0. Here are the relavent changes.

//Nested class in CScan

template<typename T>
class CCopyScan
{
friend CScan<T>;
public:
CCopyScan(T* pData, ULONG nSize) :
m_pData(pData), m_nSize(nSize)
{
}

CCopyScan() :
m_pData(NULL), m_nSize(0)
{
}

CCopyScan(CCopyScan& copyscan) :
m_pData(copyscan.m_pData), m_nSize(copyscan.m_nSize)
{
}

~CCopyScan()
{
}

CCopyScan& operator=(CCopyScan& copyscan)
{
m_nSize = copyscan.m_nSize;
CopyMemory(m_pData, copyscan.m_pData, m_nSize * sizeof(T));
return *this;
}

private:
T* m_pData;
ULONG m_nSize;
};


//Overload assignment
CScan& operator=(const CCopyScan<T>& copyscan)
{
delete [] m_pData;
m_nSize = copyscan.m_nSize;
m_pData = new T[m_nSize];
CopyMemory(m_pData, copyscan.m_pData, m_nSize * sizeof(T));
return *this;
}

//New operator()
CCopyScan<T> operator()(const unsigned long nFrom, const unsigned
long nTo)
{
if (nFrom >= m_nSize)
{
throw;
}
if (nTo >= m_nSize)
{
throw;
}
unsigned long nSize = nTo - nFrom + 1L;
if (nSize > 0)
{
return CCopyScan<T>(&m_pData[nFrom], nSize);
}
else
{
return CCopyScan<T>();
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top