anfängerfrage zu oop



  • hey

    naja zunächst möchte ich erwähnen dass ich nicht sonderlich den plan von c++ habe, besser gesagt lerne ich c++ erst...

    also da redunanter code mühsam und schlecht zu warten ist, mache ich meinen nicht-konstanten accessor etwa so:

    template<unsigned SizeX, unsigned SizeY>
    virtual Buffer<SizeX, SizeY>::EntryType& Buffer<SizeX, SizeY>::operator() (SizeType IndexX, SizeType IndexY)
    {
    	return const_cast<EntryType&>((*static_cast<Buffer<SizeX, SizeY> const*>(this))(IndexX, IndexY));
    }
    

    nun da es für die implementierung von "Buffer" mehrere möglichkeiten gibt, habe ich eine abstrakte basisklasse, namens "BufferInterface". (BufferInterface ist kein klassentemplate)

    ich habe mehrere buffer-klassen von "BufferInterface" abgeleitet, bei der implementierung von allen ist mir aufgefallen, dass der code vom nicht-konstanten accessor sehr ähnlich ist, es wird immer der konstante accessor angesprochen inkl. casting usw.

    jetzt kommt die eigentliche frage: kann ich den nicht-konstanten accessor in der basisklasse virtuell, jedoch nicht rein virtuell deklarieren und dabei etwa den code wie bei gezeigtem listing vordefinieren? ich hab dabei ja bedenken, weil ich nicht weiss, was ich da in die <> vom static_cast reintun soll. kann mir jemand dabei helfen? mein ziel ist einfach, dass die basisklassen keinen nicht-konstanten accessor definieren müssen und dass dennoch bei allen der konstante (und möglicherweise überschriebene) accessor aufgerufen wird.

    gruss



  • Ich sehe hier zwar nicht den Vorteil von Vererbung, aber so könnte das gehen:

    struct BasicBuffer {
      typedef std::size_t SizeType;
      typedef int EntryType;
      virtual EntryType& operator()(SizeType IndexX, SizeType IndexY) =0;
      virtual EntryType const& operator()(SizeType IndexX, SizeType IndexY)const=0;
    };
    template <typename Deriv>
    struct BasicBufferCRTP : BasicBuffer {
      virtual EntryType& operator()(SizeType IndexX, SizeType IndexY)
      {
        return const_cast<EntryType&>(static_cast<Deriv const&>(*this)(IndexX, IndexY));
      }
    };
    
    template<unsigned SizeX, unsigned SizeY>
    struct Buffer : BasicBufferCRTP<Buffer<SizeX, SizeY> > {
      typedef BasicBuffer::EntryType EntryType;
      typedef BasicBuffer::SizeType SizeType;
      int data;
      virtual EntryType const& operator() (SizeType IndexX, SizeType IndexY)  const
      {
        return data;
      }  
    };
    
    int main()
    {
      Buffer<2,5> b;
      std::cout << b(4,5) << '\n';
      std::cout << static_cast<Buffer<2,5> const&>(b)(4,5) << '\n';
    }
    


  • joa danke, sieht schonmal gut aus, werde ich mal so umsetzen.

    naja grund für vererbung bei meinem code, ich nutze einfach referenzen auf buffer-interfaces für verschiedene dinge, die dann den buffer je nach dem befüllen. die verschiedenen abgeleiteten instanziierbaren buffer mache ich meistens nach dem adapter pattern mit anderen klassen, z.b. einem bitmap handler usw. (vll kann man da später auch was basteln damit ich in den framebuffer schreiben kann)


Anmelden zum Antworten