Gå til innhold

Operatorer i virituele klasser


Anbefalte innlegg

Her om dagen skulle jeg lage en interface klasse av en 3D vector klasse

og den har jo operatorer (+ - * osv), men kompilatorenen vil ikke kompilere, enten savner den funsjonene i Interface klassene , eller hvis jeg bruker __interface så sier VC at operatorer i interface klasser er fyfy.

 

Så det jeg lurer på er om det er en måte å få dette til, eller en annen fornuftig måte å gjøre dette på.

Lenke til kommentar
Videoannonse
Annonse

Hadde vært fint å se koden din, for å forklare akkurat hva du gjør feil.

 

Jeg gjetter at du prøver noe ala følgende:

class CBase
{
public:
 virtual void operator +(const CBase& rhs) = 0;
};

class CDerived : public CBase
{
public:
 void operator +(const CDerived& rhs)
 {
   ...
 }
};

 

Dette kjører rett inn i begrensningene C++ har for polymorphisme. Kort sagt kan ikke kompilatoren gjøre oppslag i vtabellen både på bakgrunn av 'this' og parametertype. Hvis du vil vite mer om det, kan du lese om double dispatch og/eller visitor pattern. Alternativt kan du ty til RTTI, og bruke dynamic_cast. Noen kjappe googlesøk burde peke deg i riktig retning der også.

Lenke til kommentar

Vet ikke om dette er hva du tenker på?

#include <iostream>
template <class T>
class MyInterface {
public:
   virtual void operator+(const T s)=0;
   
};
class MyClass1 : public MyInterface<MyClass1> {
public:
   void operator +(const MyClass1 s) {
       std::cout << "Myclass1" << std::endl;
   }
};

class MyClass2 : public MyInterface<MyClass2> {
public:
   void operator +(const MyClass2 s) {
       std::cout << "Myclass2" << std::endl;
   }
};

int main (int argc, char **argv) {
   MyClass1 v;
   MyClass2 w;
   v + v;
   w + w;
   std::cin.get();
   return 0;
}

Endret av Nazgul
Lenke til kommentar

Du traff nesten spikern einaros :thumbup:

Jeg vil bruke interface siden Vector3d koden ligger i en annen DLL.

Og da forstår ikke jeg det som om Nazgul sin kode vil fungere (mulig jeg tar feil)

 

Her er noe av interface koden

 

[/code]

#pragma once

#include "Y_var.h"

 

class CVector3;

 

__interface IVector3

{

public:

virtual const CVector3 operator + (const CVector3 vVector);

virtual const CVector3 operator - (const CVector3 vVector);

virtual const CVector3 operator * (const CVector3 vVector);

virtual const CVector3 operator / (const CVector3 vVector);

};




			
				


	Endret  av Giddion
	
	

			
		
Lenke til kommentar

Det er riktig som Nazgul sier, at man kan bruke templates for å få dette til virke i enkle løsninger som dette. Skal man derimot bruke dette interfacet i et real-world-tilfelle, blir det fort tungvint, om ikke umulig, å jobbe med.

 

Si f.eks. at du vil ha membermetoder i en eller annen klasse, som kan behandle de ulike typene klasser som implementerer MyInterface. Eller at du vil ha en vector/liste av pointere til MyInterface-implementerende klasser. For all virkelig bruk av interfacet, må man oppgi hvilken underklasse det skal gjelde for.

 

Vurder også dette:

 MyInterface* EnEllerAnnenKlasse::retit();

 void main()
 {
   EnEllerAnnenKlasse x;
   MyInterface* ptr = x.retit();
 }

 

Litt av poenget er da at man ikke skal behøve å vite akkurat hva klassen man bruker gjør eller returnerer. Man forholder seg kun til de metoder interfacet eksponerer, og tar resten for gitt. Med en templateimplementasjon, lar ikke dette seg gjøre.

Lenke til kommentar
Her er noe av interface koden

 

#pragma once
#include "Y_var.h"

class CVector3;

__interface IVector3
{
public:
virtual	const CVector3	operator +	(const CVector3 vVector);
virtual	const CVector3	operator -	(const CVector3 vVector);
virtual	const CVector3	operator *	(const CVector3 vVector);
virtual	const CVector3	operator /	(const CVector3 vVector);
};

6107095[/snapback]

 

Med RTTI:

class MyVector : public IVector3
{
public:
 virtual const CVector3 operator +(const CVector3 vVector)
 {
   MyVector* derived = dynamic_cast<MyVector*>(&vVector);
   if(derived)
   {
     // vVector er av typen MyVector. 
     // gjør nødvendige operasjoner mot derived, returner objekt
   }
   else
   {
     // vVector er av en annen type, f.eks. CVector3.
     // gjør operasjoner, returner objekt
   }
 }
}

Lenke til kommentar

hmmm... Jeg har sett kjapt på teknikkene nevnt overnfor og det virker på meg som om ingen av de veldig gode å få gjennomføre for meg.

Generelt går teknikkene ut på det samme: Finne ut hvilke type man snakker om og deretter utføre korekt handling. Men fra mitt ståsted så får jeg ikke kalt på den korekte funsjonen (funsjonen befinner seg på en annen dll)

Men det er jo ikke umulig har jeg har oversett noe

 

Det er jo også en mulighet å bruke mer "normale" funsjoner :hmm:

Takker igjen for raske og fyldige svar.

Lenke til kommentar

mulig jeg var litt rask, men jeg kan ikke se hvordan jeg skal gjennomføre det uten å overføre operatorene til normale funsjoner.

 

Litt info.

Jeg har en YCore.dll som skal inneholder de "rene" og mye brukte klasser. Tilgangen til klassene i YCore blir gjennomført via Interface og klasse fabrikker.

Problemet slik jeg ser det er at jeg ikke får laget en Interface til vector3d klassen. Og hvis jeg skal gjennomføre noen av de nevnte metoden over må jeg bruke funsjoner som eksisterer på dll fila.

 

Håper jeg ble litt mer forstålig nå :)

Litt usikker på hvilke deler av programmet jeg burde poste, men i zip filen ligger alt om vector3 klassen

YCore.zip

Endret av Giddion
Lenke til kommentar
  • 2 uker senere...

Nå har jeg tenkt litt rundt omkring, og jeg var helt på jordet, operatorene til de enkle klassene jeg hadde er det vel det beste og enkleste å legge de inn i hver dll fil siden disse operatorene egentlig burde inlines. Men men da har jeg hverfall lært noe :)

 

takker for alle svar

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...