• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Przeciążanie operatorów wyjścia i dodawania (programowanie obiektowe)

Object Storage Arubacloud
+1 głos
844 wizyt
pytanie zadane 4 maja 2016 w C i C++ przez plkpiotr Stary wyjadacz (12,420 p.)

Dzień dobry! Mam do napisania kod w oparciu o programowanie obiektowe, który będzie dokonywał działań dodawania, odejmowania, mnożenia (itp.) na wektorach. Napisałem już zaczątek kodu, tzn. konstruktor, konstruktor kopiujący, destruktor, operator wyjścia, jednak napotkałem problem przy przeciążaniu operatora dodawania.
Proszę o pomoc w wyjaśnieniu co powoduje następujący błąd:
 

\main.cpp|10|error: no match for 'operator<<' in 'std::operator<< <std::char_traits<char> >((* & operator<<((* & std::operator<< <std::char_traits<char> >((* & operator<<((* & std::cout), (* & v1))), ((const char*)" +  "))), (* & v2))), ((const char*)" = ")) << Wektor::operator+(Wektor&)((* & v2))'|

Kod algebra.h

#ifndef algebra_h
#define algebra_h

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <ctime>

using namespace std;

class Wektor
{
   private:
      int szerokosc;
      int *tablica;

   public:
      Wektor(int);                                  // Konstruktor
      Wektor(Wektor&);                              // Konstruktor kopiujacy
      ~Wektor();                                    // Destruktor
      Wektor& operator= (Wektor&);                  // Przypisywanie
      Wektor operator+ (Wektor&);                   // Dodawanie
      Wektor operator- (Wektor&);                   // Odejmowanie
      Wektor operator* (Wektor&);                   // Mnozenie
      bool operator== (Wektor&);                    // Rownosc
      bool operator!= (Wektor&);                    // Sprzecznosc
      int operator[] (Wektor&);                     // Indeksowanie
      friend ostream& operator<< (ostream&,Wektor&);// Wyswietlanie
      friend istream& operator>> (istream&,Wektor&);// Wczytywanie
      Wektor& operator+= (Wektor&);                 // Zwiększanie
      Wektor& operator-= (Wektor&);                 // Zmniejszanie
      Wektor& operator*= (int);                     // Wielokrotność
};

#endif

Kod algebra.cpp
 

#include "algebra.h"

Wektor::Wektor(int s)
{
   if(s<1)
   {
      cout << "Nieprawidlowe wartosci wektora ";
      cout << ". Zostanie utworzony wektor zerowy. " << endl;
      szerokosc=0;
      tablica=NULL;
   }
   else
   {
      szerokosc=s;
      tablica=new int[szerokosc];
      for(int i=0;i<szerokosc;i++)
      {
      tablica[i]=(rand()%10)+0;
      }
   }
}

Wektor::Wektor(Wektor& v)
{
   if(v.szerokosc<1)
   {
      cout << "Nieprawidlowe wartosci wektora ";
      cout << ". Zostanie utworzony wektor zerowy. " << endl;
      szerokosc=0;
      tablica=NULL;
   }
   else
   {
      szerokosc=v.szerokosc;
      tablica=new int[szerokosc];
      for(int i=0;i<szerokosc;i++)
      {
      tablica[i]=v.tablica[i];
      }
   }
}

Wektor::~Wektor()
{
   delete [] tablica;
}

Wektor& Wektor::operator= (Wektor& v)
{
   if(this==&v) return *this;
   if(v.szerokosc==0)
   {
      szerokosc=0;
      delete [] tablica;
      tablica=NULL;
   }
   else
   {
      delete [] tablica;
      szerokosc=v.szerokosc;
      tablica=new int[szerokosc];
      for(int i=0;i<szerokosc;i++)
      {
         tablica[i]=v.tablica[i];
      }
   }
   return *this;
}

Wektor Wektor:: operator+ (Wektor& v)
{
   if(v.szerokosc==0) return *this;
   if(szerokosc==0) return v;
   Wektor w(szerokosc);
   if(szerokosc==v.szerokosc)
   {
      for(int i=0;i<szerokosc;i++)
      {
         w.tablica[i]+=tablica[i];
         w.tablica[i]+=v.tablica[i];
      }
   }
   return w;
}

std::ostream& operator << (ostream& wyjscie,Wektor& v)
{
   {
      wyjscie << "[ ";
      for(int i=0;i<v.szerokosc;i++) wyjscie << v.tablica[i] << " ";
      wyjscie << "] ";
   }
   return wyjscie;
}

Kod main.cpp

#include "algebra.h"

int main()
{
   int mnoznik;
   srand(time(NULL));
   Wektor v1(5),v2(5);
   system("cls");
   cout<<"Wektory 5-wymiarowe:"<<'\t'<<v1<<'\t'<<v2<<endl<<endl;
   cout<<v1<<" +  "<<v2<<" = "<<v1+v2<<endl;
   cout<<v1<<" -  "<<v2<<" = "<<endl;
   cout<<v1<<" *  "<<v2<<" = "<<endl;
   cout<<v1<<" == "<<v2<<" = "<<endl;
   cout<<v1<<" != "<<v2<<" = "<<endl;
   cout<<v1<<" += "<<v2<<" = "<<endl;
   cout<<v1<<" -= "<<v2<<" = "<<endl;
   cout<<v1<<" *= "<<v2<<" = "<<endl;
   cout<<v1<<" [] "<<v2<<" = "<<endl;
   cout<<v1<<" <- "<<v2<<" = "; v1=v2; cout<<v1; getchar();
   return 0;
}

 

1 odpowiedź

+3 głosów
odpowiedź 4 maja 2016 przez Radfler VIP (101,030 p.)
edycja 11 czerwca 2016 przez Radfler
 
Najlepsza

Witaj! Spójrz na ten fragment:

cout<<v1<<" +  "<<v2<<" = "<<v1+v2<<endl;
                             ^^^^^

Jak widzisz rezultatem tego wyrażenia jest obiekt typu Wektor będący pr-wartością. A teraz spójrz na operator wypisania:

std::ostream& operator << (ostream& wyjscie,Wektor& v)

Przyjmuje on jako argument referencję do l-wartości. Wystąpił tu konflikt kategorii wartości. Popraw deklarację operatora wypisania do strumienia w taki sposób:

std::ostream& operator << (ostream& wyjscie,const Wektor& v)
1
komentarz 4 maja 2016 przez plkpiotr Stary wyjadacz (12,420 p.)

Serdecznie dziękuję smiley

1
komentarz 5 maja 2016 przez Radfler VIP (101,030 p.)
edycja 5 maja 2016 przez Radfler

Ogólnie polecam Ci przyjmować argumenty funkcji przez stałą referencję const Wektor& (oczywiście tam, gdzie jest to możliwe):

Wektor(const Wektor&);    
Wektor& operator= (const Wektor&);   
Wektor operator+ (const Wektor&) const;
komentarz 6 maja 2016 przez plkpiotr Stary wyjadacz (12,420 p.)
edycja 6 maja 2016 przez plkpiotr
Czy mógłbym się dowiedzieć jaka jest różnica pomiędzy Pana wersją, a moją?

Niekoniecznie od Pana, ale nawet ze stron www, czy jakichś publikacji...
1
komentarz 6 maja 2016 przez Radfler VIP (101,030 p.)

Wykład o tym, dlaczego const jest bardzo ważny: https://www.youtube.com/watch?v=Y1KOuFYtTF4

Dla operatorów arytmetycznych czy konstruktorów kopiujących również poleca się const: http://en.cppreference.com/w/cpp/language/copy_constructor http://en.cppreference.com/w/cpp/language/copy_constructor

A ja może posłużę się takim przykładem:

void fn() {
	
  const Wektor wektor_zerowy; // stała typu 'Wektor' oznaczająca wektor zerowy

  Wektor moj_wektor;
  moj_wektor = wektor_zerowy;
  
  // linijka 6 jest nieprawidłowa:
  // wywoływany jest operator 'Wektor& operator=(Wektor&)'
  // w tym wypadku występuje niezgodność kwalifikatora const
  
}

 

1
komentarz 6 maja 2016 przez plkpiotr Stary wyjadacz (12,420 p.)
Dziękuję raz jeszcze :)

Podobne pytania

0 głosów
1 odpowiedź 970 wizyt
0 głosów
1 odpowiedź 181 wizyt
pytanie zadane 1 lutego 2020 w C i C++ przez mat19 Obywatel (1,580 p.)
+1 głos
0 odpowiedzi 348 wizyt

92,551 zapytań

141,399 odpowiedzi

319,531 komentarzy

61,938 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...