错误C2259:无法实例化抽象类 [英] error C2259: cannot instantiate abstract class

查看:225
本文介绍了错误C2259:无法实例化抽象类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆