一个简单的SafeArray封装类,还请大家参考与指教

Henry0 2005-04-30 09:16:19
最近遇到使用SAFEARRAY比较多,因为是三维图形方面,用到的SAFEARRAY一般都是一维的数组,元素个数为1(表示参数曲线),2(表示参数曲面),3(表示三维点).于是写了一个针对这方面的类.
我想值得讨论是地方有两个, 一是SAFEARRAY的使用,一就是关于通用类编写的一些准则(比如说实现正规函数,转型,以及错误处理等等),希望大家能够批评指教.

#pragma once
#include <assert.h>
#include <oleauto.h>
#include <math.h>

const double E_PRECISION = 0.0001;

template<int dimension>
class CDbSafeArray
{
public:
//constructor
explicit CDbSafeArray(double t);
CDbSafeArray(double u,double v);
CDbSafeArray(double x,double y,double z);
CDbSafeArray(const SAFEARRAY* psa);

//copy constructor
CDbSafeArray(const CDbSafeArray& rhs);

~CDbSafeArray();

public:
//operator override
SAFEARRAY** operator&();

CDbSafeArray& operator = (const CDbSafeArray& rhs);

bool Equal(double dbleft,double dbright);

bool operator == ( const CDbSafeArray& rhs);

bool operator != ( const CDbSafeArray& rhs);

public:
//data access
//for parameterized curve dimension = 1
HRESULT get_T(double& T);
HRESULT set_T(double T);

//for parameterized surface dimension = 2
HRESULT get_U(double& U);
HRESULT set_U(double U);
HRESULT get_V(double& V);
HRESULT set_V(double V);

//for 3d point dimension = 3
HRESULT get_X(double& X);
HRESULT set_X(double X);
HRESULT get_Y(double& Y);
HRESULT set_Y(double Y);
HRESULT get_Z(double& Z);
HRESULT set_Z(double Z);

//
HRESULT setdata(double T);
HRESULT getdata(double& T);

HRESULT setdata(double U,double V);
HRESULT getdata(double& U,double& V);

HRESULT setdata(double X,double Y, double Z);
HRESULT getdata(double& X,double& Y, double& Z);

public:
//safearray
SAFEARRAY* m_psa;

private:
//the length of the array(only 1,2,3 allowed)
int m_idimension;

};
...全文
129 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhousqy 2005-05-01
  • 打赏
  • 举报
回复
学习
mostideal 2005-05-01
  • 打赏
  • 举报
回复
ding
xuzheng318 2005-04-30
  • 打赏
  • 举报
回复
先帮楼主顶一下,慢慢看!
Henry0 2005-04-30
  • 打赏
  • 举报
回复
-----------------------使用-------------------------------------------------
CDbSafeArray<3> sa3(0.1,2.4,4.5);
CDbSafeArray<3> sa4(0.1,2.4,4.5);
CDbSafeArray<3> sa5(0.1,2.4,4.1);

CDbSafeArray<3> sa6(sa5);

if(sa4 != sa5)
AfxMessageBox(_T("sa4 != sa5"));
if(sa6 == sa5)
AfxMessageBox(_T("sa6 = sa5"));
if(sa5 == sa3)
AfxMessageBox(_T("sa3 = sa5"));
Henry0 2005-04-30
  • 打赏
  • 举报
回复
template<int dimension>
HRESULT CDbSafeArray<dimension>::get_T(double& T)
{
HRESULT hr = S_OK;
assert(dimension == 1);
if(dimension != 1)
return E_FAIL;
//access data
double* pd = NULL;
hr = ::SafeArrayAccessData(m_psa,(void**)&pd);
if(FAILED(hr)) return hr;
T = pd[0];
hr = ::SafeArrayUnaccessData(m_psa);
if(FAILED(hr)) return hr;
return hr;
}
template<int dimension>
HRESULT CDbSafeArray<dimension>::set_T(double T)
{
HRESULT hr = S_OK;
assert(dimension == 1);
if(dimension != 1)
return E_FAIL;
//access data
double* pd = NULL;
hr = ::SafeArrayAccessData(m_psa,(void**)&pd);
if(FAILED(hr)) return hr;
pd[0] = T;
hr = ::SafeArrayUnaccessData(m_psa);
if(FAILED(hr)) return hr;
return hr;
}

template<int dimension>
HRESULT CDbSafeArray<dimension>::get_U(double& U)
{
HRESULT hr = S_OK;
assert(dimension == 2);
if(dimension != 2)
return E_FAIL;
//access data
double* pd = NULL;
hr = ::SafeArrayAccessData(m_psa,(void**)&pd);
if(FAILED(hr)) return hr;
U = pd[0];
hr = ::SafeArrayUnaccessData(m_psa);
if(FAILED(hr)) return hr;
return hr;
}
template<int dimension>
HRESULT CDbSafeArray<dimension>::set_U(double U)
{
HRESULT hr = S_OK;
assert(dimension == 2);
if(dimension != 2)
return E_FAIL;
//access data
double* pd = NULL;
hr = ::SafeArrayAccessData(m_psa,(void**)&pd);
if(FAILED(hr)) return hr;
pd[0] = U;
hr = ::SafeArrayUnaccessData(m_psa);
if(FAILED(hr)) return hr;
return hr;
}
template<int dimension>
HRESULT CDbSafeArray<dimension>::get_V(double& V)
{
HRESULT hr = S_OK;
assert(dimension == 2);
if(dimension != 2)
return E_FAIL;
//access data
double* pd = NULL;
hr = ::SafeArrayAccessData(m_psa,(void**)&pd);
if(FAILED(hr)) return hr;
V = pd[1];
hr = ::SafeArrayUnaccessData(m_psa);
if(FAILED(hr)) return hr;
return hr;
}
template<int dimension>
HRESULT CDbSafeArray<dimension>::set_V(double V)
{
HRESULT hr = S_OK;
assert(dimension == 2);
if(dimension != 2)
return E_FAIL;
//access data
double* pd = NULL;
hr = ::SafeArrayAccessData(m_psa,(void**)&pd);
if(FAILED(hr)) return hr;
pd[1] = V;
hr = ::SafeArrayUnaccessData(m_psa);
if(FAILED(hr)) return hr;
return hr;
}

template<int dimension>
HRESULT CDbSafeArray<dimension>::get_X(double& X)
{
HRESULT hr = S_OK;
assert(dimension == 3);
if(dimension != 3)
return E_FAIL;
//access data
double* pd = NULL;
hr = ::SafeArrayAccessData(m_psa,(void**)&pd);
if(FAILED(hr)) return hr;
X = pd[0];
hr = ::SafeArrayUnaccessData(m_psa);
if(FAILED(hr)) return hr;
return hr;
}
template<int dimension>
HRESULT CDbSafeArray<dimension>::set_X(double X)
{
HRESULT hr = S_OK;
assert(dimension == 3);
if(dimension != 3)
return E_FAIL;
//access data
double* pd = NULL;
hr = ::SafeArrayAccessData(m_psa,(void**)&pd);
if(FAILED(hr)) return hr;
pd[0] = X;
hr = ::SafeArrayUnaccessData(m_psa);
if(FAILED(hr)) return hr;
return hr;
}
template<int dimension>
HRESULT CDbSafeArray<dimension>::get_Y(double& Y)
{
HRESULT hr = S_OK;
assert(dimension == 3);
if(dimension != 3)
return E_FAIL;
//access data
double* pd = NULL;
hr = ::SafeArrayAccessData(m_psa,(void**)&pd);
if(FAILED(hr)) return hr;
Y = pd[1];
hr = ::SafeArrayUnaccessData(m_psa);
if(FAILED(hr)) return hr;
return hr;
}
template<int dimension>
HRESULT CDbSafeArray<dimension>::set_Y(double Y)
{
HRESULT hr = S_OK;
assert(dimension == 3);
if(dimension != 3)
return E_FAIL;
//access data
double* pd = NULL;
hr = ::SafeArrayAccessData(m_psa,(void**)&pd);
if(FAILED(hr)) return hr;
pd[1] = Y;
hr = ::SafeArrayUnaccessData(m_psa);
if(FAILED(hr)) return hr;
return hr;
}
template<int dimension>
HRESULT CDbSafeArray<dimension>::get_Z(double& Z)
{
HRESULT hr = S_OK;
assert(dimension == 3);
if(dimension != 3)
return E_FAIL;
//access data
double* pd = NULL;
hr = ::SafeArrayAccessData(m_psa,(void**)&pd);
if(FAILED(hr)) return hr;
Z = pd[2];
hr = ::SafeArrayUnaccessData(m_psa);
if(FAILED(hr)) return hr;
return hr;
}
template<int dimension>
HRESULT CDbSafeArray<dimension>::set_Z(double Z)
{
HRESULT hr = S_OK;
assert(dimension == 3);
if(dimension != 3)
return E_FAIL;
//access data
double* pd = NULL;
hr = ::SafeArrayAccessData(m_psa,(void**)&pd);
if(FAILED(hr)) return hr;
pd[2] = Z;
hr = ::SafeArrayUnaccessData(m_psa);
if(FAILED(hr)) return hr;
return hr;
}

template<int dimension>
HRESULT setdata(double T)
{
return set_T(T);
}
template<int dimension>
HRESULT getdata(double& T)
{
return get_T(T);
}

template<int dimension>
HRESULT setdata(double U,double V)
{
HRESULT hr = S_OK;
assert(dimension == 2);
if(dimension != 2)
return E_FAIL;
//access data
double* pd = NULL;
hr = ::SafeArrayAccessData(m_psa,(void**)&pd);
if(FAILED(hr)) return hr;
pd[0] = U;
pd[1] = V;
hr = ::SafeArrayUnaccessData(m_psa);
if(FAILED(hr)) return hr;
return hr;
}
template<int dimension>
HRESULT getdata(double& U,double& V)
{
HRESULT hr = S_OK;
assert(dimension == 2);
if(dimension != 2)
return E_FAIL;
//access data
double* pd = NULL;
hr = ::SafeArrayAccessData(m_psa,(void**)&pd);
if(FAILED(hr)) return hr;
U = pd[0];
V = pd[1];
hr = ::SafeArrayUnaccessData(m_psa);
if(FAILED(hr)) return hr;
return hr;
}
template<int dimension>
HRESULT setdata(double X,double Y, double Z)
{
HRESULT hr = S_OK;
assert(dimension == 3);
if(dimension != 3)
return E_FAIL;
//access data
double* pd = NULL;
hr = ::SafeArrayAccessData(m_psa,(void**)&pd);
if(FAILED(hr)) return hr;
pd[0] = X;
pd[1] = Y;
pd[2] = Z;
hr = ::SafeArrayUnaccessData(m_psa);
if(FAILED(hr)) return hr;
return hr;
}
template<int dimension>
HRESULT getdata(double& X,double& Y, double& Z)
{
HRESULT hr = S_OK;
assert(dimension == 3);
if(dimension != 3)
return E_FAIL;
//access data
double* pd = NULL;
hr = ::SafeArrayAccessData(m_psa,(void**)&pd);
if(FAILED(hr)) return hr;
X = pd[0];
Y = pd[1];
Z = pd[2];
hr = ::SafeArrayUnaccessData(m_psa);
if(FAILED(hr)) return hr;
return hr;
}
Henry0 2005-04-30
  • 打赏
  • 举报
回复
template<int dimension>
CDbSafeArray<dimension>::CDbSafeArray(double t):m_psa(NULL),m_idimension(dimension)
{
assert(dimension == 1);
try
{
if(dimension != 1) throw;
//create
m_psa = ::SafeArrayCreateVector(VT_R8,0,1);
if(m_psa == NULL)
throw;
//access data
double* pd = NULL;
HRESULT hr = ::SafeArrayAccessData(m_psa,(void**)&pd);
if(FAILED(hr))
throw;
pd[0] = t;
hr = ::SafeArrayUnaccessData(m_psa);
if(FAILED(hr))
throw;
m_idimension = dimension;
}
catch(...)
{
if(m_psa != NULL)
{
::SafeArrayDestroy(m_psa);
m_psa = NULL;
}
}
}

template<int dimension>
CDbSafeArray<dimension>::CDbSafeArray(double u,double v):m_psa(NULL),m_idimension(dimension)
{
assert(dimension == 2);
try
{
if(dimension != 2) throw;
//create
m_psa = ::SafeArrayCreateVector(VT_R8,0,2);
if(m_psa == NULL)
throw;

//access data
double* pd = NULL;
HRESULT hr = ::SafeArrayAccessData(m_psa,(void**)&pd);
if(FAILED(hr))
throw;
pd[0] = u;
pd[1] = v;
hr = ::SafeArrayUnaccessData(m_psa);
if(FAILED(hr))
throw;
m_idimension = dimension;
}
catch(...)
{
if(m_psa != NULL)
{
::SafeArrayDestroy(m_psa);
m_psa = NULL;
}
}
}
template<int dimension>
CDbSafeArray<dimension>::CDbSafeArray(double x,double y,double z):m_psa(NULL),m_idimension(dimension)
{
assert(dimension == 3);
try
{
if(dimension != 3) throw;
//create
m_psa = ::SafeArrayCreateVector(VT_R8,0,3);
if(m_psa == NULL)
throw;
//access data
double* pd = NULL;
HRESULT hr = ::SafeArrayAccessData(m_psa,(void**)&pd);
if(FAILED(hr))
throw;
pd[0] = x;
pd[1] = y;
pd[2] = z;
hr = ::SafeArrayUnaccessData(m_psa);
if(FAILED(hr))
throw;
m_idimension = dimension;
}
catch(...)
{
if(m_psa != NULL)
{
::SafeArrayDestroy(m_psa);
m_psa = NULL;
}
}
}
template<int dimension>
CDbSafeArray<dimension>::CDbSafeArray(const SAFEARRAY* psa):m_psa(NULL)
{
//psa must created
assert(psa != NULL);
try
{
if(psa == NULL)
throw;
LONG lUpDim;
HRESULT hr = ::SafeArrayGetUBound(psa,1,&lUpDim);
if(FAILED(hr)) throw;
if(dimension != ++lUpDim)
throw;
m_psa = psa;
m_idimension = dimension;

}
catch (_com_error)
{
}
catch(...)
{
}

}

template<int dimension>
CDbSafeArray<dimension>::CDbSafeArray(const CDbSafeArray& rhs): m_psa(NULL)
{
operator=(rhs);
}
template<int dimension>
CDbSafeArray<dimension>::~CDbSafeArray()
{
if(m_psa != NULL)
{
::SafeArrayDestroy(m_psa);
m_psa = NULL;
}
}



template<int dimension>
SAFEARRAY** CDbSafeArray<dimension>::operator&()
{
// Directly accessing the address of the internal SAFEARRAY is assumed
// to only be done with the intent to use as an out argument in a call
// and should therefore only be done when it is NULL or leaking will occur.
// If this is not the intent, access the m_psa member directly.
assert(!m_psa);
try
{
if(m_psa == NULL)
throw;
return &m_psa;

}
catch (...)
{
}
}
template<int dimension>
CDbSafeArray<dimension>& CDbSafeArray<dimension>::operator = (const CDbSafeArray& rhs)
{
assert(rhs.m_psa);
try
{
if(rhs.m_psa == NULL)
throw;
if(dimension != rhs.m_idimension)
throw;
if (&m_psa == &rhs.m_psa)
throw;

HRESULT hr = S_OK;
if (rhs.m_psa)
{
//it will create a safearray for m_psa
hr = SafeArrayCopy(rhs.m_psa, &m_psa);
}
assert(SUCCEEDED(hr));
if(FAILED(hr))
throw;
m_idimension = dimension;
}
catch (...)
{
}

return *this;
}

template<int dimension>
bool CDbSafeArray<dimension>::Equal(double dbleft,double dbright)
{
if(fabs(dbleft - dbright)<E_PRECISION)
return true;
else
return false;

}
template<int dimension>
bool CDbSafeArray<dimension>::operator == ( const CDbSafeArray& rhs)
{
HRESULT hr = S_OK;
assert(rhs.m_psa);
try
{
if(rhs.m_psa == NULL)
throw;
if(m_idimension!= rhs.m_idimension)
throw;
if (&m_psa == &rhs.m_psa)
return true;

if (rhs.m_psa)
{
double *pd1 = NULL;
double *pd2 = NULL;
hr = ::SafeArrayAccessData(m_psa,(void**)&pd1);
if(FAILED(hr)) throw;
hr = ::SafeArrayAccessData(rhs.m_psa,(void**)&pd2);
if(FAILED(hr)) throw;
if(m_idimension == 1)
{
if(Equal(pd1[0],pd2[0]))
return true;
else
return false;

}
else if(m_idimension == 2)
{
if(Equal(pd1[0],pd2[0]) && Equal(pd1[1],pd2[1]))
return true;
else
return false;
}
else if(m_idimension == 3)
{
if(Equal(pd1[0],pd2[0]) && Equal(pd1[1],pd2[1]) && Equal(pd1[2],pd2[2]))
return true;
else
return false;
}
hr = ::SafeArrayUnaccessData(m_psa);
if(FAILED(hr)) throw;
hr = ::SafeArrayUnaccessData(rhs.m_psa);
if(FAILED(hr)) throw;
}

}
catch (...)
{
}
}

template<int dimension>
bool CDbSafeArray<dimension>::operator != ( const CDbSafeArray& rhs)
{
if(*this == rhs)
return false;
else
return true;

}

64,649

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧