Jak użyć metody pochodnej obiektem bazowym, tak aby działało?

0
#pragma once
#include<iostream
class Funkcja
{
protected:
	double x;
public:
	Funkcja();
	Funkcja* Funkcja::setX(double x);
	double getX();
	virtual double oblicz();
	virtual ~Funkcja();
};

Funkcja::Funkcja()
{
}

Funkcja* Funkcja::setX(double x)
{
	this->x = x;
	return this;
}

double Funkcja::getX()
{
	return x;
}



double Funkcja::oblicz()
{
	std::cout << "wyowlanie dla funkcja";
	return 0;
}


Funkcja::~Funkcja()
{
}
#pragma once
#include"Funkcja.hpp"
#include<cmath>
class Sinus : public Funkcja {

public:
	Sinus();
	~Sinus();
	virtual double oblicz();

};


class AlgorytmNumeryczny
{
protected:
	Funkcja funkcja;
	double epsilon;
	AlgorytmNumeryczny(Funkcja funkcja,double epsilon= 0.0001);
public:
	~AlgorytmNumeryczny();
	void ustawEpsilon(double epsilon);

	virtual double oblicz()=0;
};


class MiejscaZerowe: public AlgorytmNumeryczny {

protected:
	double a;//pocz
	double b;//koniec
public:
	MiejscaZerowe(Funkcja funkcja);
	void ustawPrzedzial(double a, double b);
		double oblicz();


};


#include<iostream>
using namespace std;
#define e 2.71828
#define pi 3.1415

AlgorytmNumeryczny::AlgorytmNumeryczny(Funkcja funkcja, double epsilon):funkcja(funkcja),
epsilon(epsilon)
{
}


AlgorytmNumeryczny::~AlgorytmNumeryczny()
{
}

void AlgorytmNumeryczny::ustawEpsilon(double epsilon)
{
	this->epsilon = epsilon;
}

MiejscaZerowe::MiejscaZerowe(Funkcja funkcja):AlgorytmNumeryczny(funkcja,0.0001)
{
	//std::cout << "wywolane m zerowe";
}

void MiejscaZerowe::ustawPrzedzial(double a=-1.0, double b=1.0)
{
	this->a = a;
	this->b = b;
	//std::cout << "ustaw przedzial a   b"<<a<<"    "<<b<<std::endl;
}

double MiejscaZerowe::oblicz()
{
	double x1=999, x1_value=9999;
	funkcja.setX(a);
	double p_value = static_cast<Sinus&>(funkcja).oblicz();
	cout << "p_value: " << p_value << endl;
	funkcja.setX(b);
	double k_value = static_cast<Sinus&>(funkcja).oblicz();
	cout << "k_value: " << k_value << endl;
	if (p_value*k_value  > 0)
	{
		std::cout << p_value*k_value << "zwroc cokolwiek";
		return 0;
	}
	while (abs(a - b) > epsilon) {

		x1 = (a + b) / 2;
		funkcja.setX(a);
		p_value =static_cast<Sinus&>(funkcja).oblicz();
		x1_value = (funkcja.setX(x1)->oblicz());
		if (x1_value == 0) // jeżeli znaleźliśmy miejsce zerowe
			break;
		else if (x1_value* p_value < 0)
			b = x1; // nadpisywanie prawego krańca przedziału
		else
			a = x1; // nadpisywanie lewego krańca przedziału
	}
	
	return x1;
}





Sinus::Sinus()
{
}

Sinus::~Sinus()
{
}

double Sinus::oblicz()
{

	cout << "sinus oblicz";
	return sin(x*(pi/180));
}

Mimo że kastuje na Klase sinus to i tak używa mi metody klasy bazowej Dlaczego?Co mam zrobić inaczej?(ja chce użyć metody oblicz() klasy pochodnej Sinus


double p_value = static_cast<Sinus&>(funkcja).oblicz();

Przepraszam za długi kod ale nie wiem co mogłem uciąć aby było cztejniej

0

Klasa MiejsceZerowe nie dziedziczy po klasie Sinus. Dziedziczy po klasie AlgorytmNumeryczny i nic ponadto.

1

funkcja to obiekt typu Funkcja, a nie Sinus. Rzutowanie tego na Sinus& nie sprawi automagicznie, że nagle funkcja umie się zachowywać jak obiekt klasy Sinus, co więcej to UB.

Polimorfizm się osiąga poprzez wskaźnik (lub referencję) do klasy bazowej, który wskazuje na rzeczywisty obiekt klasy pochodnej.

#include <iostream>
using namespace std;

struct X
{
    virtual void foo() { cout << "X\n"; }
};

struct Y : public X
{
    virtual void foo() override { cout << "Y\n"; }
};

int main()
{
    X x;
    x.foo();
    
    Y y;
    y.foo();
    
    X& yr = y;
    yr.foo();
    
    X* yptr = &y;
    yptr->foo();
}

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