Polimorfizm

0

Hej! Przerabiam sobie polimorfizm i używanie abstrakcyjnych funkcji wirtualnych. Zaczyna brakować mi pomysłów co zrobiłem nie tak, a pewnie to jakaś głupota. Pomyślałem, że zwrócę się do Was o pomoc. :)

Napisałem program, który ma docelowo przy pomocy użycia abstrakcyjnej klasy Figure wywoływać odpowiednie obliczenia/informacje dla kwadratu, prostopadłościanu i odcinka. Program się odpala, natomiast wywołuje wyłącznie napis "Calculate" z klasy abstrakcyjnej Figure.

Figure.h

#pragma once

class Figure
{
public:
	Figure() {};

	virtual void calculate()
	{
		std::cout << "Calculate: \n";
	}

	~Figure() {};
};

Segment.h

#pragma once
#include "Figure.h"

class Segment : public Figure
{
private:
	double x;

public:
	Segment(double newX = 0)
	{
		this->x = newX;
	}

	void calculate(double x)
	{
		std::cout << "Segment length: " << x << std::endl;
	}
};

Square.h

#pragma once
#include "Figure.h"

class Square : public Figure
{
private:
	double x;

public:
	Square(double newX = 0)
	{
		this->x = newX;
	}

	void calculate(double x)
	{
		std::cout << "Perimeter of the square: " << 4 * x << std::endl;
		std::cout << "Square Area: " << x * x << std::endl;
	}
};

Cuboid.h

#pragma once
#include "Figure.h"

class Cuboid : public Figure
{
private:
	double x;
	double y;
	double z;

public:
	Cuboid(double newX = 0, double newY = 0, double newZ = 0)
	{
		this->x = newX;
		this->y = newY;
		this->z = newZ;
	}

	void calculate(double x, double y, double z)
	{
		std::cout << "Permiter of a cuboid: " << 4 * (x+y+z) << std::endl;
		std::cout << "Cuboid area: " << 2*(x*y) + 2*(x*z) + 2*(y*z) << std::endl;
		std::cout << "The cuboid volume: " << x * y * z << std::endl;
	}
};

Main.cpp

#include <iostream>
#include "Figure.h"
#include "Segment.h"
#include "Square.h"
#include "Cuboid.h"

int main()
{
    Figure** tab = new Figure * [6];

    tab[0] = new Segment();
    tab[1] = new Segment(5);
    tab[2] = new Square();
    tab[3] = new Square(10);
    tab[4] = new Cuboid();
    tab[5] = new Cuboid(5,10,15);

    for (int i = 0; i < 6; i++) {
        tab[i]->calculate();
        delete tab[i];
    }

    delete[] tab;

    getchar();
    return 0;
}
1

W klasach dziedziczących definiujesz nowe metody calculate, a nie nadpisujesz istniejącej. Aby uniknąć takich błędów (tzn żeby kompilator wyrzucił błąd gdy to zrobisz) używaj słowa kluczowego override

struct A
{
    virtual void foo();
    void bar();
};
 
struct B : A
{
    void foo() const override; // Error: B::foo does not override A::foo
                               // (signature mismatch)
    void foo() override; // OK: B::foo overrides A::foo
    void bar() override; // Error: A::bar is not virtual
};
0

Dodałem słowo kluczowe override, natomiast wtedy podkreśla mi metodę calculate(). Tworząc swój program bazowałem min na wiadomościach stąd: https://www.p-programowanie.p[...]polimorfizm-metody-wirtualne/ , zamieszczam link, bo mój program jest dość analogiczny a jednak nie działa. :/

1

Override tylko powoduje że kompilator jawnie da znać, że robisz błąd i przerwie kompilację. Nie naprawia to samego błędu - definiujesz inną funkcję o nazwie calculate. Musisz mieć identyczny interfejs jak chcesz overridować (czyli w tym przypadku: 0 parametrów)

0

No dobrze tylko, że robię sobie zadanie do poćwiczenia, które ma uwzględnić obiekt domyślny o parametrach 0 i sparametryzowany z parametrami podanymi przez użytkownika

0

No ale co ma parametryzowanie obiektu do interfejsu funkcji wirtualnej? Obiekt sobie parametryzuj, a funkcji nie ruszaj.

0

Dobra, rozumiem już ostatecznie co było nie tak. Dziękuję za pomoc :) Wystarczyło usunąć argumenty z metod calculate.
Dzięki jeszcze raz :)

0
Kratos napisał(a):

Dobra, rozumiem już ostatecznie co było nie tak. Dziękuję za pomoc :) Wystarczyło usunąć argumenty z metod calculate.
Dzięki jeszcze raz :)

Tak na prawdę chodziło o to żeby wszystkie funkcje calculate() miały takie same argumenty. Czyli usunięcie ich się w to wlicza.

1 użytkowników online, w tym zalogowanych: 0, gości: 1