2013-05-22 20 views
11

Mam projekt dla szkoły w C++ i utknąłem na jednej części: Muszę przeciążyć operatorów + i * do pracy z figurami geometrycznymi. Nie stanowiło to problemu, ale tutaj, gdzie to nie działa: muszę zadeklarować operatora jako czystą metodę wirtualną, w klasie abstrakcyjnej, z której wywodzą się wszystkie inne klasy.Czysty wirtualny operator

#include<iostream> 
using namespace std; 

class Figabs { 
protected: 
    int fel; 
public: 
    int getFEL() { return fel; } 
    virtual Figabs operator +()=0; /*this is where I get an error: function returning abstract class “Figabs” is not allowed : function Figabs::operator+ is a pure virtual function */ 
}; 

class Coord { 
public: 
    int cx, cy; 
public: 
    Coord(){ 
     cx = cy = 0; 
    } 

    Coord (const int x, const int y) { 
     cx = x; 
     cy = y; 
    } 

    Coord (const Coord &din) { 
     cx = din.cx; 
     cy = din.cy; 
    } 

    ~Coord() { } 
    void setX(const int val) { cx = val; } ; 
    void setY(const int val) { cy = val; }; 
    int getX() { return cx; } 
    int getY() { return cy; } 
}; 

class Point : public Coord, public Figabs { //one of the figures 

public: 
    Point() { 
     setX(0); 
     setY(0); 
     fel = 0; 
    } 

    Point(const int x, const int y): Coord (x,y) { 
     fel = 0; 
    } 

    Point(const Point &din): Coord (din) { 
     fel = din.fel; 
    } 

    ~Point() { } 

    Point operator +(const Coord &vector) { /*this works perfectly when I delete the declaration from the abstract class Figabs, but I don’t know how to make them work together */ 
     int xp = cx + vector.cx; 
     int yp = cy + vector.cy; 
     return (Point (xp, yp)); 
    } 

    Point operator *(const Coord &vector) { 
     Point temp; 
     temp.cx = cx * vector.cx; 
     temp.cy = cy * vector.cy; 
     return (temp); 
    } 
}; 

Dziękuję i proszę o cierpliwość ze mną, jest to mój pierwszy kontakt z C++.

+0

Czy zamiast tego próbowałeś umieścić deklarację w pliku .H? – Shark

+3

@Shark: co dokładnie by to zmieniło? – Mat

+1

wirtualny operator Figabs +() = 0 bez argumentów -> Operator punktu + (const Coord i wektor) z innym typem zwróconym? ich podpis musi być taki sam ... – Exceptyon

Odpowiedz

9

Jak zaznaczyły inne plakaty, zadanie jest daleka od banalne, a operator+ zwykle nie jest członkiem. Istnieją dwa kwestie, które powinny zostać poruszone:

  1. Jeśli obsługują `FigAbs + Coord`, to należy również wspierać ` Coord + FigAbs`. Pierwszy może być członkiem (nie ma tam prawdziwego problemu ); drugi, jeśli ma być członkiem, musi być członkiem "Coorda", co prawdopodobnie nie jest tym, co jest potrzebne.
  2. Każda rozsądna implementacja operatora `` musi zwrócić wartość o wartości . I nie można (normalnie) zwrócić klasy polimorficznej przez wartość: ; trzeba coś takiego idiomu Letter koperty dla tym pracować: klasa bazowa powinna wyglądać mniej więcej tak:
     
    class Figure : BinaryOperators<Figure, Coord> 
    { 
        Figure* myImpl; 
    public: 
        Figure& operator+=(Coord const& translation) 
        { 
         myImpl->operator+=(translation); 
         return *this; 
        } 
    }; 
    
    Oczywiście, trzeba metod fabrycznych poprawnie instancji `Figure` dla każdego innego typu, o wirtualna funkcja `clone` oraz konstruktor kopii, przypisanie i destruktor obsługujący głęboką kopię. (`BinaryOperators` jest klasy szablon, który implementuje` operator + `w kategoriach ` operatora + = `;. Jest to zwykły sposób, aby zapewnić binarnych operatorów)

koniec chciałbym twierdzić, że ta jest operatorem przeciążającym nadużycia. Pojęcie dodawania nie ma zastosowania do figur geometrycznych. To, co robisz, nazywa się translacją, a logicznym rozwiązaniem jest udostępnienie funkcji składowej, która to robi, a nie dodawanie przeciążenia w postaci .

3

Figabs zawiera czystą funkcję składową wirtualny virtual Figabs operator +()=0; to oznacza, że ​​nie można utworzyć wystąpienia Figabs

rozważenia:

virtual Figabs& operator +()=0; 
/*Now you will not be returning an actual instance but can return derived class instances* 
+7

Do czego odnosi się ta zwracana wartość? – BoBTFish

+0

Dziękuję, że sprawił, że błąd zniknął, ale teraz klasa pochodna, gdzie mam: operator Puncte + (const Coord i wektor) mówi błąd: typ zwracany nie jest identyczny ani kowariantny z typem powrotu Figabs i zastąpionej funkcji wirtualnej Figab: : operator + – Casandra

+0

@BoBTFish Całkowicie widzę i zgadzam się. Jest to bardzo konkretna odpowiedź, zwracająca uwagę na przyczynę błędu kompilatora, a nie całkowite rozwiązanie problemu. – DuncanACoulter

0

Proszę spojrzeć na poniższy link do informacji przydatnych kawałka związanego pytanie

overriding virtual function return type differs and is not covariant

wirtualna Figa Operator bs +() = 0; // W ur nie przechodząc jakiekolwiek parametry I/P

ale w klasie pochodnej ur przekazywania parametrów

punkt operatora + (const Coord & wektor) // W ur wysyłania I/parametr p.

+0

To więcej komentarza niż odpowiedzi. – Shark