错误C2259:无法实例化抽象类 [英] error C2259: cannot instantiate abstract class
问题描述
我使用Visual Studio 2010创建一个ATL项目,并在此项目中添加一个ATL简单对象类。在构建过程中没有任何错误。但是当我声明一个类对象,比如 CCartoPoint pt 时,我收到错误消息错误C2259:'CCartoPoint':无法实例化抽象类
在以下代码中,错误消息来自方法' STDMETHODIMP CCartoPoint :: get_Centroid(ICartoPoint ** pCentroidVal)'。
我已经检查了 .h 文件中的方法数量, .h 文件和 .cpp 文件相同。
* .IDL文件:
[
object,
uuid (14428BC6-A897- 4268 -8FFD-B4947DEDDFC6),
dual ,
不可扩展,
pointer_default(唯一)
]
interface ICartoPoint:IDispatch {
[propget, id( 2 )] HRESULT X([out,retval] DOUBLE * pVal);
[propput,id( 2 )] HRESULT X([ in ] DOUBLE newVal);
[propget,id( 3 )] HRESULT Y([out,retval] DOUBLE * pVal);
[propput,id( 3 )] HRESULT Y([ in ] DOUBLE newVal);
};
[
object,
uuid (238155D0-220A-4BFA-90D2-46E27461E314),
dual,
不可扩展,
pointer_default(唯一)
]
interface ICartoGeometry:IDispatch {
[propget,id(< span class =code-digit> 1 )] HRESULT区域([out,retval] DOUBLE * pAreaVal);
[propget,id( 2 )] HRESULT Centroid([out,retval] ICartoPoint ** pCentroidVal);
[propget,id( 3 )] HRESULT GeometryType([out,retval] cartoGeometryType * pTypeVal);
// [propget,id(4)] HRESULT坐标([out,retval] ICartoCoordinate ** pCdsVal ,[out] DOUBLE * pCountVal);
[propget,id( 5 )] HRESULT NumGeometries([out,retval] LONG * pNumberVal );
[propget,id( 6 )] HRESULT NumPoints([out,retval] LONG * pNumberVal);
[propget,id( 7 )] HRESULT坐标([out,retval] ICartoCoordinate ** pVal);
};
* .h文件
class ATL_NO_VTABLE CCartoPoint:
public CComObjectRootEx< CComSingleThreadModel>,
public CComCoClass< CCartoPoint,& CLSID_CartoPoint>,
public IDispatchImpl< ICartoPoint,& IID_ICartoPoint,& LIBID_GeometryObjectLib , / * wMajor = * / 1 , / * wMinor = * / 0> ;,
public IDispatchImpl< ICartoGeometry,& IID_ICartoGeometry,& LIBID_GeometryObjectLib, / * wMajor = * / 1 , / * wMinor = * / 0>
{
public :
CCartoPoint()
{
m_pCoordinate = 新坐标( 0 , 0 );
GeometryFactory工厂;
m_pPoint = factory.createPoint(* m_pCoordinate);
}
CCartoPoint(DOUBLE x,DOUBLE y)
{
m_pCoordinate = new 坐标(x,y);
GeometryFactory工厂;
m_pPoint = factory.createPoint(* m_pCoordinate);
}
DECLARE_REGISTRY_RESOURCEID(IDR_CARTOPOINT)
BEGIN_COM_MAP(CCartoPoint)
COM_INTERFACE_ENTRY(ICartoPoint)
COM_INTERFACE_ENTRY2 (IDispatch,ICartoPoint)
COM_INTERFACE_ENTRY(ICartoGeometry)
END_COM_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT FinalConstruct( )
{
return S_OK;
}
void FinalRelease()
{
}
< span class =code-keyword> public :
STDMETHOD(get_X)(DOUBLE * pVal);
STDMETHOD(put_X)(DOUBLE newVal);
STDMETHOD(get_Y)(DOUBLE * pVal);
STDMETHOD(put_Y)(DOUBLE newVal);
public :
STDMETHOD(get_Area)(DOUBLE * pAreaVal);
STDMETHOD(get_Centroid)(ICartoPoint ** pCentroidVal);
STDMETHOD(get_GeometryType)(cartoGeometryType * pTypeVal);
STDMETHOD(get_NumGeometries)(LONG * pNumberVal);
STDMETHOD(get_NumPoints)(LONG * pNumberVal);
STDMETHOD(get_Coordinates)(ICartoCoordinate ** pVal);
private :
Point * m_pPoint;
坐标* m_pCoordinate;
};
OBJECT_ENTRY_AUTO( __ uuidof (CartoPoint),CCartoPoint)
* .cpp文件
STDMETHODIMP CCartoPoint :: get_X(DOUBLE * pVal)
{
return S_OK;
}
STDMETHODIMP CCartoPoint :: put_X(DOUBLE newVal)
{
return S_OK;
}
STDMETHODIMP CCartoPoint :: get_Y(DOUBLE * pVal)
{
return S_OK;
}
STDMETHODIMP CCartoPoint :: put_Y(DOUBLE newVal)
{
return S_OK;
}
STDMETHODIMP CCartoPoint :: get_Area(DOUBLE * pAreaVal)
{
return S_OK;
}
STDMETHODIMP CCartoPoint :: get_Centroid(ICartoPoint ** pCentroidVal)
{
CCartoPoint pt;
return S_OK;
}
STDMETHODIMP CCartoPoint :: get_GeometryType(cartoGeometryType * pTypeVal)
{
return S_OK;
}
STDMETHODIMP CCartoPoint :: get_NumGeometries(LONG * pNumberVal)
{
return S_OK;
}
STDMETHODIMP CCartoPoint :: get_NumPoints(LONG * pNumberVal)
{
return S_OK;
}
STDMETHODIMP CCartoPoint :: get_Coordinates(ICartoCoordinate ** pVal)
{
return S_OK;
}
抽象类的想法是限制其实例化。这样的类不是为了拥有它的实例而设计的,它被设计成在某些派生类中用作基类,其中一些也可以保持抽象。抽象类可能有纯抽象函数(它们的占位符在虚拟表中,但不是实现,即使它们实际上在其他函数中使用,因此使用这些类的实例将是危险的。但是,它不是必需的;类可以是设计抽象的,它的一些功能可以是虚拟的但是可以实现(伪抽象或非抽象)。
-SA
我没有检查你是否缺少任何API但是类定义的ATL_NO_VTABLE规范告诉编译器该类不会被实例化。
[如果你解决了这个问题,仍然可能有一个或多个需要实现的API ...]
I create a ATL project with Visual Studio 2010, and add a ATL simple object class in this project. There is no any error during the building process. But when I declare a class object, such as CCartoPoint pt, I get the error message "error C2259: 'CCartoPoint' : cannot instantiate abstract class"
In the following codes, the error message is from the method 'STDMETHODIMP CCartoPoint::get_Centroid( ICartoPoint** pCentroidVal)'.
I have checked the the numbers of methods in IDL file, in .h file and the .cpp file is same.
The *.IDL file:
[
object,
uuid(14428BC6-A897-4268-8FFD-B4947DEDDFC6),
dual,
nonextensible,
pointer_default(unique)
]
interface ICartoPoint : IDispatch{
[propget, id(2)] HRESULT X([out, retval] DOUBLE* pVal);
[propput, id(2)] HRESULT X([in] DOUBLE newVal);
[propget, id(3)] HRESULT Y([out, retval] DOUBLE* pVal);
[propput, id(3)] HRESULT Y([in] DOUBLE newVal);
};
[
object,
uuid(238155D0-220A-4BFA-90D2-46E27461E314),
dual,
nonextensible,
pointer_default(unique)
]
interface ICartoGeometry : IDispatch{
[propget, id(1)] HRESULT Area([out, retval] DOUBLE* pAreaVal);
[propget, id(2)] HRESULT Centroid([out, retval] ICartoPoint** pCentroidVal);
[propget, id(3)] HRESULT GeometryType([out, retval] cartoGeometryType* pTypeVal);
//[propget, id(4)] HRESULT Coordinates([out, retval] ICartoCoordinate** pCdsVal,[out] DOUBLE* pCountVal);
[propget, id(5)] HRESULT NumGeometries([out, retval] LONG* pNumberVal);
[propget, id(6)] HRESULT NumPoints([out, retval] LONG* pNumberVal);
[propget, id(7)] HRESULT Coordinates([out, retval] ICartoCoordinate** pVal);
};
The *.h file
class ATL_NO_VTABLE CCartoPoint :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CCartoPoint, &CLSID_CartoPoint>,
public IDispatchImpl<ICartoPoint, &IID_ICartoPoint, &LIBID_GeometryObjectLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
public IDispatchImpl<ICartoGeometry, &IID_ICartoGeometry, &LIBID_GeometryObjectLib, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
public:
CCartoPoint()
{
m_pCoordinate = new Coordinate(0,0);
GeometryFactory factory;
m_pPoint = factory.createPoint(*m_pCoordinate);
}
CCartoPoint(DOUBLE x, DOUBLE y)
{
m_pCoordinate = new Coordinate(x,y);
GeometryFactory factory;
m_pPoint = factory.createPoint(*m_pCoordinate);
}
DECLARE_REGISTRY_RESOURCEID(IDR_CARTOPOINT)
BEGIN_COM_MAP(CCartoPoint)
COM_INTERFACE_ENTRY(ICartoPoint)
COM_INTERFACE_ENTRY2(IDispatch,ICartoPoint)
COM_INTERFACE_ENTRY(ICartoGeometry)
END_COM_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT FinalConstruct()
{
return S_OK;
}
void FinalRelease()
{
}
public:
STDMETHOD(get_X)(DOUBLE* pVal);
STDMETHOD(put_X)(DOUBLE newVal);
STDMETHOD(get_Y)(DOUBLE* pVal);
STDMETHOD(put_Y)(DOUBLE newVal);
public:
STDMETHOD(get_Area)(DOUBLE* pAreaVal);
STDMETHOD(get_Centroid)( ICartoPoint** pCentroidVal);
STDMETHOD(get_GeometryType)( cartoGeometryType* pTypeVal);
STDMETHOD(get_NumGeometries)(LONG* pNumberVal);
STDMETHOD(get_NumPoints)( LONG* pNumberVal);
STDMETHOD(get_Coordinates)(ICartoCoordinate** pVal);
private:
Point* m_pPoint;
Coordinate* m_pCoordinate;
};
OBJECT_ENTRY_AUTO(__uuidof(CartoPoint), CCartoPoint)
The *.cpp file
STDMETHODIMP CCartoPoint::get_X(DOUBLE* pVal)
{
return S_OK;
}
STDMETHODIMP CCartoPoint::put_X(DOUBLE newVal)
{
return S_OK;
}
STDMETHODIMP CCartoPoint::get_Y(DOUBLE* pVal)
{
return S_OK;
}
STDMETHODIMP CCartoPoint::put_Y(DOUBLE newVal)
{
return S_OK;
}
STDMETHODIMP CCartoPoint::get_Area(DOUBLE* pAreaVal)
{
return S_OK;
}
STDMETHODIMP CCartoPoint::get_Centroid( ICartoPoint** pCentroidVal)
{
CCartoPoint pt;
return S_OK;
}
STDMETHODIMP CCartoPoint::get_GeometryType( cartoGeometryType* pTypeVal)
{
return S_OK;
}
STDMETHODIMP CCartoPoint::get_NumGeometries(LONG* pNumberVal)
{
return S_OK;
}
STDMETHODIMP CCartoPoint::get_NumPoints( LONG* pNumberVal)
{
return S_OK;
}
STDMETHODIMP CCartoPoint::get_Coordinates(ICartoCoordinate** pVal)
{
return S_OK;
}
The idea of abstract class is to limit its instantiation. Such class is not designed for having instances of it, it is designed to be used as a base class in some derived classes, some of which also may remain abstract. And abstract class may have pure abstract functions (which have their placeholder in a virtual table, but not implementation, even though they are actually used in other functions, so using instances of such classes would be dangerous. Formally, however, it's not required; a class can be abstract by design, and some functions of it can be virtual but implemented (pseudo-abstract or non-abstract).
—SA
I didn't check if you are missing any APIs but the ATL_NO_VTABLE spec on the class definition tells the compiler that the class will not be instantiated.
[If you fix that, there still might be one or more APIs that need to be implemented...]
这篇关于错误C2259:无法实例化抽象类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!