Inheritance of a diamond when only one object implements a basic function

Yes, I used to inherit diamonds, but this time my problem seemed rather unique. I have an IShaderResource interface that acts as a base class. I have another interface that comes from IShaderResource called IVertexBuffer. Then I have an implementation of the basic D3D11ShaderResource interface, which comes from IShaderResource. Subsequently, I have an object called D3D11VertexBuffer that extends D3D11ShaderResource and implements IVertexBuffer. So now my hierarchy looks like this.

IShaderResource / \ / \ IVertexBuffer D3D11ShaderResource \ / \ / D3D11VertexBuffer 

IShaderResource has only 1 pure virtual function. The part where this differs from ordinary diamond inheritance is that IVertexBuffer does not implement this function. It remains abstract, while D3D11ShaderResource implements this function. When I actually inherit IShaderResource for both derived classes, it still considers that I have an abstract function. For my system to work, I need IVertexBuffer to be retrieved from IShaderResource. Implemented tools will be in the dll, dynamically loaded at the beginning of execution, but will remain connected throughout the life of the program. Thus, any objects created from the DLL anywhere can be accessed through the interface, but types will be defined behind the interface throughout the entire program life cycle. For example, if you loaded the d3d11 library and created a vertex buffer, you will get ptr IVertexBuffer, which points to an instance of D3D11VertexBuffer, and after that no other vertex buffer tools will be available. This means that in the renderer, I can pass the IShaderResource to the D3D11ShaderResource, knowing what it will be. (note that * this outside the visualization tool will defeat the purpose of the interfaces)

In my Renderer interface there are functions in which I would like to pass an IShaderResource, for example, IVertexBuffer, and perform actions on the base D3D11VertexBuffer through only part of D3D11ShaderResource, while others will receive IVertexBuffer and perform actions in D3D11Vertexbuffer. To do this, I need to extract from IShaderResource to ensure that D3D11ShaderResource is a complete type of IShaderResource, and that D3D11VertexBuffer inherits from both IVertexBuffer and D3D11ShaderResource.

I click 4000 lines of code, so I will just post offensive excerpts.

IShaderResource

 class IShaderResource { public: struct INIT_DESC { SYNC_USAGE usage; }; public: // virtual destructor for derived classes virtual ~IShaderResource() {} // the resource usage hint virtual IRenderUtility::SYNC_USAGE GetUsageType() = 0; }; 

IVertexBuffer

 class IVertexBuffer : public virtual IShaderResource { public: struct INIT_DESC : public IShaderResource::INIT_DESC { const void * Data; unsigned int ByteWidth; unsigned int ByteStride; }; public: // virtual destructor for derived classes virtual ~IVertexBuffer() {} // the resource usage hint virtual IRenderUtility::SYNC_USAGE GetUsageType() = 0; }; 

D3D11ShaderResource

 class D3D11RenderUtility::D3D11ShaderResource : public virtual IRenderUtility::IShaderResource { public: struct INIT_DESC { IRenderUtility::SYNC_USAGE usage; ID3D11ShaderResourceView * resourceView; }; public: // default constructor D3D11ShaderResource(INIT_DESC & desc) : m_Usage(desc.usage), m_ResourceView(desc.resourceView) {} // virtual destructor for derived classes virtual ~D3D11ShaderResource() {} // obtains the resource usage hint IRenderUtility::SYNC_USAGE GetUsageType() {return m_Usage;} // used to obtain the resource view of the object ComPtr<ID3D11ShaderResourceView> GetResourceView() const {return m_ResourceView;} protected: IRenderUtility::SYNC_USAGE m_Usage; ComPtr<ID3D11ShaderResourceView> m_ResourceView; }; 

D3D11VertexBuffer

 class D3D11RenderUtility::D3D11VertexBuffer : public IRenderUtility::IVertexBuffer , public D3D11RenderUtility::D3D11ShaderResource { public: struct INIT_DESC : public D3D11ShaderResource::INIT_DESC { ID3D11Buffer * buf; }; private: // disable copy constructor D3D11VertexBuffer(const D3D11VertexBuffer & buf); // disable assignment operator void operator=(const D3D11VertexBuffer & buf); public: // default constructor D3D11VertexBuffer(INIT_DESC & desc) : D3D11ShaderResource(desc), m_Buffer(desc.buf) {} // virtual destructor for derived classes virtual ~D3D11VertexBuffer() {} // used to obtain the d3d11 vertex buffer pointer ComPtr<ID3D11Buffer> GetBuffer() const {return m_Buffer;} private: ComPtr<ID3D11Buffer> m_Buffer; }; 

IRenderUtility :: SYNC_USAGE is a simple enum beyond the scope, and ComPtr is a small intelligent shell that I made to automatically issue com pointers. Other than that, the rest is pretty obvious.

btw, the actual error is: error C2259: 'SYNC::D3D11RenderUtility::D3D11VertexBuffer' : cannot instantiate abstract class 2> due to following members: 2> 'SYNC::IRenderUtility::SYNC_USAGE SYNC::IRenderUtility::IVertexBuffer::GetUsageType(void)' : is abstract

SYNC is the namespace that all this is in.

+4
source share
2 answers

What you use here is what the definition of language calls "dominance." If only one of your two intermediate classes overrides the virtual function defined in the virtual database, then this definition is also applied in the derived class. As @chuex said, you need to remove the redundant declaration in IVertexBuffer because it violates the premise for dominance to apply.

Adding redundant code for readability or any other reason is usually a bad idea, if only because it simplifies maintenance. Here he wins what your class hierarchy is trying to accomplish.

+1
source

I think you need to remove the GetUsageType in IVertexBuffer . It seems redundant to have it there And in the IShaderResource database.

+2
source

All Articles