Umístění přetíženého operátoru << do třídy – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

Umístění přetíženého operátoru << do třídy – C / C++ – Fórum – Programujte.comUmístění přetíženého operátoru << do třídy – C / C++ – Fórum – Programujte.com

 

Toto vlákno bylo označeno za vyřešené — příspěvek s řešením.
Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
mfaudio0
Duch
28. 11. 2011   #1
-
0
-

Dobrý den, chtěl bych se zeptat, kam do třídy complex vložit definici přetíženého operátoru <<. Operátor + lze vložit přímo do třídy, ale << mi to nedovolí.

soubor - Complex.h

#ifndef _COMPLEX_H
#define _COMPLEX_H

class complex {
private:
	double re, im;
public:
	complex() {}
	complex(double r, double i) {re = r; im = i;}
	
	friend complex operator+(complex a, complex b) {complex p(real(a)+real(b), imag(a)+imag(b)); return p; }
};

#endif

soubor - Main.c

#include <iostream>
#include <stdio.h>

#include "Complex.h"

using namespace std;
int main() {
	cout << "Complex1 running ..." << endl;	
	
	complex x(4, 8);
	cout << "x   = " << x << endl;

	return 0;
}

Kód přetíženého operátoru mi Microsoft Visual 2010 povolí akorát do souboru Main.c před funkci main. Já bych ho chtěl ale vložit do definice třídy, at je její součástí. Nebo se to používá jinak?

Kód přetíženého operátoru

ostream &operator<<(ostream &stream, complex z) {
	stream << "(" << real(z) << ", " << imag(z) << ") ";
	return stream;
}

Díky za odpověď.

Nahlásit jako SPAM
IP: 78.45.11.–
Reklama
Reklama
liborb
~ Redaktor
+18
Guru
28. 11. 2011   #2
-
0
-

Tak si založ Complex.cpp, protože tam to patří jako (nejlépe) všechna (ne-inline) implementace.

Nahlásit jako SPAM
IP: 78.80.52.–
KIIV+42
God of flame
28. 11. 2011   #3
-
+1
-
Zajímavé
Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
mfaudio0
Duch
28. 11. 2011   #4
-
0
-

Doma listuju 3mi knížkami a celou dobu hledám na googlu jak se správně programuje v C++ ale bez úspechů. Jediný na co jsem přišel je toto

complex.cpp 

#include "stdafx.h"
#include <iostream>

#include "Complex.h"

using namespace std;

// kosntruktory
complex::complex() {}
complex::complex(double r, double i) {re = r; im = i;}

// verejne metody
void complex::setReal(double r) {re = r;}
void complex::setImag(double i) {im = i;}
double complex::getReal() {return re;}
double complex::getImag() {return im;}
	
// spratelene metody
double real(complex& a) { return a.re; }
double imag(complex& a) { return a.im; }
complex operator+(complex a, complex b) {
   complex p(real(a)+real(b), imag(a)+imag(b)); 
   return p; 
}

complex.h

#ifndef _COMPLEX_H
#define _COMPLEX_H

class complex {
private:
   double re, im;
public:
   complex();      // konstruktor
   complex(double r, double i);    // konstruktor

   // deklarace verejnych funkci
   void setReal(double r);
   void setImag(double i);
   double getReal();
   double getImag();

   // deklarace spratelenych funkci
   friend double real(complex& a);
   friend double imag(complex& a);
   friend complex operator+(complex a, complex b);
};

#endif

Main.cpp

#include <iostream>	
#include "Complex.h"

using namespace std;

int main() {
   cout << "Complex1 running ..." << endl;
   complex x(1, 1);
   cout << "x     = " << x << endl;
   complex z(2, 3);
   cout << "y     = " << z << endl;
   cout << "x + z = " << x + z << endl;
   return 0;
}

Je to takhle z pohledu zkušeného programátora v pořádku? V hlavičce není nic definováno. Vše je definováno v complex.cpp. Stále ale je problém s tím přetíženým operátorem <<.

ostream &operator<<(ostream &stream, complex z) {
   stream << "(" << z.getReal() << ", " << z.getImag() << ") ";
return stream;
}

Nikam jinam než před funkci main to vložit nejde.

Nahlásit jako SPAM
IP: 78.45.11.–
liborb
~ Redaktor
+18
Guru
28. 11. 2011   #5
-
0
-

A co ti to píše za chybu, když to nejde?

Zasláno z mobilního telefonu.

Nahlásit jako SPAM
IP: 82.145.211.–
ondra.holub+1
Stálý člen
28. 11. 2011   #6
-
0
-

Operátor << (pokud tedy má sloužit pro výstup do streamu) nemůže být metodou třídy complex, protože na jeho levé straně je stream, nikoliv třída complex.

Je možné ho deklarovat (a případně i definovat) přímo v definici třídy jako friend, ale ani tak nebude metodou třídy complex.

Obecně je ovšem zbytečné ten operátor definovat jako friend. Pokud má vypisovat nějaké vnitřní proměnné, může se k nim dostat přes vhodné get metody. Pokud tyto metody nesmí existovat z důvodu utajení, neměly by se tyto hodnoty ani vypisovat. Pokud je to vypisování přece jenom potřeba (třeba pro debuggování apod.), stačí si napsat metodu, která má jeden parametr - stream, do kterého se vypisuje a tu z operátoru<< zavolat.

Nahlásit jako SPAM
IP: 194.138.12.–
mfaudio0
Duch
28. 11. 2011   #7
-
0
-

No když to udělám stejně jako s operátorem + tak při překladu v Microsoft Visual Studio 2010 to vyhodí tyto chyby

1>f:\work\c++\mvs2010\knihivna\knihivna\complex.h(22): error C2143: syntax error : missing ';' before '&'
1>f:\work\c++\mvs2010\knihivna\knihivna\complex.h(22): error C2433: 'ostream' : 'friend' not permitted on data declarations
1>f:\work\c++\mvs2010\knihivna\knihivna\complex.h(22): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>f:\work\c++\mvs2010\knihivna\knihivna\complex.h(22): error C2061: syntax error : identifier 'ostream'
1>f:\work\c++\mvs2010\knihivna\knihivna\complex.h(22): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>f:\work\c++\mvs2010\knihivna\knihivna\complex.h(22): error C2805: binary 'operator <<' has too few parameters
1>f:\work\c++\mvs2010\knihivna\knihivna\main.cpp(14): error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'complex' (or there is no acceptable conversion)
1>          c:\program files\microsoft visual studio 10.0\vc\include\ostream(679): could be 'std::basic_ostream<_Elem,_Traits> &std::operator <<<char,std::char_traits<char>>(std::basic_ostream<_Elem,_Traits> &,const char *)'
1>          with
1>          [
1>              _Elem=char,
1>              _Traits=std::char_traits<char>
1>          ]

a dále výpis pokračuje pro všechny datové typy co sjou v C++

Nahlásit jako SPAM
IP: 78.45.11.–
Řešení
ondra.holub+1
Stálý člen
28. 11. 2011   #8
-
0
-
Vyřešeno Nejlepší odpověď

#6 ondra.holub
Můžeš to udělat jako metodu třídy complex, ale nepůjde to používat "normálně":

#include <iostream>

class complex {
private:
	double re, im;
public:
	complex() {}
	complex(double r, double i) {re = r; im = i;}

	double Re() const { return re; }
	double Im() const { return im; }

	std::ostream& operator<<(std::ostream& os) const { os << "re = " << re << " im = " << im; return os; }
};

int main()
{
    complex c(1.2, 3.4);
    c << std::cout << '\n'; // To asi neni to, co jsme chteli
}

Nebo to napsat zvlášť:

#include <iostream>

class complex {
private:
	double re, im;
public:
	complex() {}
	complex(double r, double i) {re = r; im = i;}

	double Re() const { return re; }
	double Im() const { return im; }
};

std::ostream& operator<<(std::ostream& os, const complex& c)
{
    os << "re = " << c.Re() << " im = " << c.Im();
    return os;
}

int main()
{
    complex c(1.2, 3.4);
    std::cout << c << '\n'; // To uz vypada normalne
}

Nebo zavést kamarádšoft klíčovým slovem friend:

#include <iostream>

class complex {
private:
	double re, im;
public:
	complex() {}
	complex(double r, double i) {re = r; im = i;}

	double Re() const { return re; }
	double Im() const { return im; }

	friend std::ostream& operator<<(std::ostream& os, const complex& c);
};

std::ostream& operator<<(std::ostream& os, const complex& c)
{
    os << "re = " << c.re << " im = " << c.im;
    return os;
}

int main()
{
    complex c(1.2, 3.4);
    std::cout << c << '\n'; // To uz vypada normalne
}

Nebo zavést extra metodu a operátor definovat mimo třídu (to se hodí hlavně v případě hierarchicky zděděných tříd - pak stačí metodu Dump udělat virtuální a v každém potomkovi ji předefinovat):

#include <iostream>

class complex {
private:
	double re, im;
public:
	complex() {}
	complex(double r, double i) {re = r; im = i;}

	double Re() const { return re; }
	double Im() const { return im; }

	void Dump(std::ostream& os) const
	{
	    os << "re = " << re << " im = " << im;
	}
};

std::ostream& operator<<(std::ostream& os, const complex& c)
{
    c.Dump(os);
    return os;
}

int main()
{
    complex c(1.2, 3.4);
    std::cout << c << '\n'; // To uz vypada normalne
}

A určitě existuje spousta dalších možností, které mě nenapadly.

Nahlásit jako SPAM
IP: 194.138.12.–
mfaudio0
Duch
28. 11. 2011   #9
-
0
-

Díky moc Ondro za informace. Když tedy ten operátor nemá být součástí třídy complex, kam by bylo vhodné ho umístit? V Main.cpp se mi to nelíbí, tak asi do nějakého externího cpp s dalšími pomocnými funkcemi?

Nahlásit jako SPAM
IP: 78.45.11.–
ondra.holub+1
Stálý člen
28. 11. 2011   #10
-
0
-

#9 mfaudio
Tam, kde jsou metody třídy complex. Sice není její metodou, ale logicky k té třídě patří a myslím, že každý ho tam bude i hledat. A deklarovat také tam, kde je deklarována třída complex.

Nahlásit jako SPAM
IP: 194.138.12.–
mfaudio0
Duch
28. 11. 2011   #11
-
0
-

No to právě nejde, alespoň tak, jak to dělám já.

do complex.h (do deklarace třídy)

    ostream &operator<<(ostream &stream, complex z);

do complex.cpp

    její definici

Výsledkem jsou následující chyby při překladu

1>  Main.cpp
1>f:\work\c++\mvs2010\knihivna\knihivna\complex.h(21): error C2143: syntax error : missing ';' before '&'
1>f:\work\c++\mvs2010\knihivna\knihivna\complex.h(21): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>f:\work\c++\mvs2010\knihivna\knihivna\complex.h(21): error C2061: syntax error : identifier 'ostream'
1>f:\work\c++\mvs2010\knihivna\knihivna\complex.h(21): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>f:\work\c++\mvs2010\knihivna\knihivna\complex.h(21): error C2805: binary 'operator <<' has too few parameters
1>f:\work\c++\mvs2010\knihivna\knihivna\main.cpp(14): error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'complex' (or there is no acceptable conversion)
1>          c:\program files\microsoft visual studio 10.0\vc\include\ostream(679): could be 'std::basic_ostream<_Elem,_Traits> &std::operator <<<char,std::char_traits<char>>(std::basic_ostream<_Elem,_Traits> &,const char *)'
1>          with
1>          [
1>              _Elem=char,
1>              _Traits=std::char_traits<char>
1>          ]

radek 21 je deklarace operatoru v complex.h

Nahlásit jako SPAM
IP: 78.45.11.–
ondra.holub+1
Stálý člen
28. 11. 2011   #12
-
0
-

#11 mfaudio
A nechybí ti tam třeba #include <iostream> ?

Nahlásit jako SPAM
IP: 194.138.12.–
mfaudio0
Duch
28. 11. 2011   #13
-
0
-

No pravda, v complex.h jsem ho neměl. Byl ale v Main.cpp i complex.cpp. Po přidání stále stejna chyba.

Nahlásit jako SPAM
IP: 78.45.11.–
mfaudio0
Duch
28. 11. 2011   #14
-
0
-

ale ... promin, az ted jsem si vsiml ze jsi tady vkladal take kody ... diky moc za snahu ... je mi to jasne ... jak dlouho děláš v C++?

Nahlásit jako SPAM
IP: 78.45.11.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 117 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032016 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý