Rozbudowa klas

0

Hej wszystkim, muszę rozbudować klasy wielomianu deklaracjami:

liczbaObiektow - pole przechowujące liczbę istniejących obiektów klasy wielomian,
Wyzeruj(wielomian&) - funkcja, która wyzeruje współczynniki wielomianu,
wielomian(const wielomian&) - konstruktor kopiujący,
wielomian(wielomian&&) - konstruktor przenoszący, (zadanie dla chętnych, podczas kompilacji należy dodać opcję -std=c++0x)
Lecz nie mam pojęcia jak to ugryźć, czy mogę prosić o jakąś pomoc ?

Tak wygląda mój kod

using namespace std;
#include <iostream>

class wielomian{
	private:
		int s;
		double* W;
	public:
		wielomian();
		wielomian(int);
		int PobierzStopien();
		double PobierzWspolczynnik(int);
		void ZapiszWspolczynnik(int,double);
		~wielomian();
		static int liczbaObiektow;
		friend void Wyzeruj(wielomian&); 
		wielomian(const wielomian&);
		wielomian(wielomian&&);
};
wielomian::wielomian(){
	s=0; W=new double[1]; W[0]=0.0;
}
wielomian::wielomian(int stopien){
	s=stopien; 
	W=new double[stopien+1]; 
	for(int i=0;i <= stopien;i++)W[i]=0.0;
}
int wielomian::PobierzStopien(){
	return s;
}
double wielomian::PobierzWspolczynnik(int indeks){
	if(indeks < 0) return W[0];
	if(indeks > s) return W[s];
	return W[indeks];
}
void wielomian::ZapiszWspolczynnik(int indeks,double wartosc){
	if(indeks < 0) indeks=0;
	if(indeks > s) indeks=s;
	W[indeks]=wartosc;
}
	
wielomian::~wielomian(){
	delete[] W;
}
wielomian::static int liczbaObiektow;


wielomian::friend void Wyzeruj(wielomian&); 


wielomian::wielomian(const wielomian&);


wielomian(wielomian&&);


int main(){
	wielomian w1,w2(4);
	w1.ZapiszWspolczynnik(0,3.4);
	w2.ZapiszWspolczynnik(4,-2.5);
	cout << w1.PobierzWspolczynnik(0)<< "\n";
	cout << w2.PobierzWspolczynnik(7)<< "\n";
}
1

A nie prościej byłoby zapytać autora kodu?

czy mogę prosić o jakąś pomoc ?

Jakiej pomocy oczekujesz? Potrzebujesz podpowiedzi odnośnie książek/tutoriali?

0

Jakaś wskazówka odnośnie static inta, const wielomian&&

0

liczbaObiektow - pole przechowujące liczbę istniejących obiektów klasy wielomian

Czyli pozostaje już tylko dodać inkrementacja zmiennej w konstruktorach i dekrementację w destruktorze.

wielomian(const wielomian&) - konstruktor kopiujący,

wielomian( const wielomian& w )
: s {w.s}
{
    W = new double[s+1]; 
    for( int i=0 ; i <= s ; ++i ) W[i]=w.W[i];
}

wielomian(wielomian&&) - konstruktor przenoszący, (zadanie dla chętnych, podczas kompilacji należy dodać opcję -std=c++0x)

wielomian( wielomian&& w )
: s {0}, W {nullptr}
{
    swap(w,w.W);
    swap(s,w.s);
}
0

Celowy overkill:

#include <iostream>
#include <vector>
#include <atomic>

#define LOG(x) std::cerr << __PRETTY_FUNCTION__ << " " #x "[" << (x) << "]\n"

template<typename T>
struct InstanceCounter
{
    InstanceCounter() {
        LOG(instanceCount);
        ++instanceCount;
    }
    
    InstanceCounter(const InstanceCounter&) {
        LOG(instanceCount);
        ++instanceCount;
    }
    
    InstanceCounter(InstanceCounter&&) {
        LOG(instanceCount);
        ++instanceCount;
    }
    
    InstanceCounter& operator=(const InstanceCounter&) = default;
    InstanceCounter& operator=(InstanceCounter&&) = default;
    
    ~InstanceCounter() {
        --instanceCount;
        LOG(instanceCount);
    }
    
    static size_t count() {
        return instanceCount;
    }
private:
    static std::atomic<size_t> instanceCount;
};

template<typename T>
std::atomic<size_t> InstanceCounter<T>::instanceCount;

struct AnyPolynomialTag 
{
    static size_t count()
    {
        return InstanceCounter<AnyPolynomialTag>::count();
    }
};

template<typename T>
class Polynomial {
public:
    Polynomial() = default;
    
    Polynomial(std::initializer_list<T> l)
        : a{l}
    {}
    
    T value(T x) const {
        T y{};
        for (auto ai : a) {
            y = y * x + ai;
        }
        return y;
    }
    
    T operator()(T x) const {
        return this->value(x);
    }
    
    size_t degree() const {
        return a.size();
    }
    
    void clear() {
        a.clear();
    }
    
    static size_t count() {
        return InstanceCounter<Polynomial>::count();
    }
private:
    std::vector<T> a;
    InstanceCounter<Polynomial> instanceCount;
    InstanceCounter<AnyPolynomialTag> anyPolynomialCount;
};


int main()
{
    Polynomial<double> p1;
    Polynomial<double> p2{ 1.0, -2.0, 1.0};
    Polynomial<int> p3{-1, 3};
    p1 = p2;
    
    LOG(Polynomial<double>::count());
    LOG(Polynomial<int>::count());
    LOG(AnyPolynomialTag::count());
    
    double x;
    while (std::cin >> x) {
        std::cout << "f(" << x << ") = " << p1(x) << '\n'; 
    }
    
    return 0;
}

https://wandbox.org/permlink/dK0YdmnDqRY6W1TR

Wynik uruchomienia:

InstanceCounter<T>::InstanceCounter() [with T = Polynomial<double>] instanceCount[0]
InstanceCounter<T>::InstanceCounter() [with T = AnyPolynomialTag] instanceCount[0]
InstanceCounter<T>::InstanceCounter() [with T = Polynomial<double>] instanceCount[1]
InstanceCounter<T>::InstanceCounter() [with T = AnyPolynomialTag] instanceCount[1]
InstanceCounter<T>::InstanceCounter() [with T = Polynomial<int>] instanceCount[0]
InstanceCounter<T>::InstanceCounter() [with T = AnyPolynomialTag] instanceCount[2]
int main() Polynomial<double>::count()[2]
int main() Polynomial<int>::count()[1]
int main() AnyPolynomialTag::count()[3]

f(0) = 1
f(1) = 0
f(2) = 1
f(3) = 4
f(-1) = 4

InstanceCounter<T>::~InstanceCounter() [with T = AnyPolynomialTag] instanceCount[2]
InstanceCounter<T>::~InstanceCounter() [with T = Polynomial<int>] instanceCount[0]
InstanceCounter<T>::~InstanceCounter() [with T = AnyPolynomialTag] instanceCount[1]
InstanceCounter<T>::~InstanceCounter() [with T = Polynomial<double>] instanceCount[1]
InstanceCounter<T>::~InstanceCounter() [with T = AnyPolynomialTag] instanceCount[0]
InstanceCounter<T>::~InstanceCounter() [with T = Polynomial<double>] instanceCount[0]
0

Tak wygląda fragment klasy, lecz wyrzuca błąd podczas kompilacji

wielomian::~wielomian(){
	delete[] W;
}
int wielomian::liczbaObiektow=0;


void wielomian::Wyzeruj(wielomian&){
    delete W;
   // delete [] s;
}


wielomian::wielomian( const wielomian& w )
: s {w.s}
{
    W = new double[s+1];
    for( int i=0 ; i <= s ; ++i ) W[i]=w.W[i];
}


wielomian::wielomian() s {0}, W {nullptr};
{
    int tmp;
    tmp=w;
    w=w.W;
    w.W=tmp;

    tmp=s;
    s=w.s;
    w.s=tmp;
} 

0

Naprawdę nie wiem gdzie popełniam błąd czy mogę prosić o jakieś wskazówki?

0
#include <iostream>

using namespace std;

class wielomian{
    private:
		int s;
		double* W;
	public:
		wielomian();
		wielomian(int);
		int PobierzStopien();
		double PobierzWspolczynnik(int);
		void ZapiszWspolczynnik(int,double);
		~wielomian();
		static int liczbaObiektow;
		void Wyzeruj(wielomian&);
		wielomian(const wielomian&);
    	wielomian(wielomian &&);
};
wielomian::wielomian(){
	s=0; W=new double[1]; W[0]=0.0;
}
wielomian::wielomian(int stopien){
	s=stopien;
	W=new double[stopien+1];
	for(int i=0;i <= stopien;i++)W[i]=0.0;
}
int wielomian::PobierzStopien(){
	return s;
}
double wielomian::PobierzWspolczynnik(int indeks){
	if(indeks < 0) return W[0];
	if(indeks > s) return W[s];
	return W[indeks];
}
void wielomian::ZapiszWspolczynnik(int indeks,double wartosc){
	if(indeks < 0) indeks=0;
	if(indeks > s) indeks=s;
	W[indeks]=wartosc;
}

wielomian::~wielomian(){
	delete[] W;
}
int wielomian::liczbaObiektow=0;


void wielomian::Wyzeruj(wielomian&){
    delete W;
//    delete [] s;
}


wielomian::wielomian( const wielomian& w )
: s {w.s}
{
    W = new double[s+1];
    for( int i=0 ; i <= s ; ++i ) W[i]=w.W[i];
}


wielomian::wielomian(wielomian && w)
{
    std::swap(W, w.W);
    std::swap(s, w.s);
}

int main(){
	wielomian w1,w2(4);
	w1.ZapiszWspolczynnik(0,3.4);
	w2.ZapiszWspolczynnik(4,-2.5);
	cout << w1.PobierzWspolczynnik(0)<< "\n";
	cout << w2.PobierzWspolczynnik(7)<< "\n";
}


1

Weź mój kod, wywal szablony.
W pieszym szablonie po prostu usuń T, w drugim T zastąp jakimś typem (np double) i gotowe (no prawie, bo trzeba dodać parę funkcjonalności, które miałeś, a nie były treścią zadania).

0

Hej wszystkim, muszę wykonać kolejną rozbudowę tych klas, pomożecie ?
operator+ - dodaje dwa wielomiany za pomocą operatora +,

operator[] - zwraca współczynnik wielomianu o podanym indeksie (służy do odczytu i zapisu współczynnika !)

operator<< - definiuje zachowanie strumienia wyjściowego <<. Jeżeli wywołamy go dla argumentu cout to na ekranie zobaczymy wielomian w postaci W[s]x^s+W[s-1]x^s-1+...+W[1]x^1+W[0].

operator=(const wielomian &) - operator przypisania,

operator=(wielomian&&) - operator przeniesienia

1

Towarzyszu, pomożemy. Ale w czym?

0
using namespace std;
#include <iostream>

class wielomian{
	private:
		int s;
		double* W;
	public:
		wielomian();
		wielomian(int);
		int PobierzStopien();
		double PobierzWspolczynnik(int);
		void ZapiszWspolczynnik(int,double);
		~wielomian();
		/*--cz.2.--*/
		static int liczbaObiektow;
		friend void Wyzeruj(wielomian&); 
		wielomian(const wielomian&);
		wielomian(wielomian&&);
};
wielomian::wielomian(){
	s=0; W=new double[1]; W[0]=0.0;
	liczbaObiektow++;
}
wielomian::wielomian(int stopien){
	s=stopien; 
	W=new double[stopien+1]; 
	for(int i=0;i <= stopien;i++)W[i]=0.0;
	liczbaObiektow++;
}
int wielomian::PobierzStopien(){
	return s;
}
double wielomian::PobierzWspolczynnik(int indeks){
	if(indeks < 0) return W[0];
	if(indeks > s) return W[s];
	return W[indeks];
}
void wielomian::ZapiszWspolczynnik(int indeks,double wartosc){
	if(indeks < 0) indeks=0;
	if(indeks > s) indeks=s;
	W[indeks]=wartosc;
}
	
wielomian::~wielomian(){
	delete[] W;
	liczbaObiektow--;
}
int wielomian::liczbaObiektow=0;
void Wyzeruj(wielomian& x){
	for(int i=0;i<=x.s;i++)x.W[i]=0;
	}
wielomian::wielomian(const wielomian& x){
	s=x.s;
	W=new double[s+1];
	for(int i=0;i <= s;i++)W[i]=x.W[i];
	liczbaObiektow++;
}
wielomian::wielomian(wielomian &&x){
	s=x.s;
	W=x.W;
	x.W=nullptr;
	liczbaObiektow++;
}
int main(){
	wielomian w1,w2(4);
	w1.ZapiszWspolczynnik(0,3.4);
	w2.ZapiszWspolczynnik(4,-2.5);
	cout << w1.PobierzWspolczynnik(0)<< "\n";
	Wyzeruj(w2);
	cout << w2.PobierzWspolczynnik(7)<< "\n";
	wielomian w3=w1;
	wielomian w4(std::move(w2)); /*Konstruktor przenoszący*/
}```

Do tego kodu muszę dołożyć friend wielomian operator+(const wielomian&,const wielomian&);
		double& operator[](int);
		friend ostream& operator<<(ostream&,wielomian&);
		wielomian& operator=(const wielomian&);
		wielomian& operator=(wielomian&&);
0

https://dsp.krzaq.cc/post/304/jak-przeladowywac-operatory-w-mojej-klasie/ - przeczytaj, spróbuj, w razie pytań - pytaj

0

Ja bym zasugerował zrobić niezmienny (tak to jest po polsku?) czuli immutable.
Tak, jak teraz jest zrobiony zmienny (mutable) jest tam przynajmniej kilka zalążków błędów.
Jeśli byś tkwił przy zmiennym, to dodać zabezpieczenia.

Najstarsi Górale nie wiedzą, skąd niekonsekwencje, jak np funkcja Wyzeruj zamiast metoda operująca na własnej instancji (oczywiście nie ma dla niej miejsca w immutable).

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