Üdv!
Van egy C++ osztályom, aminek van egy privát adattagja, ami konstans. Nyilván ezt inicializálni kell a konstruktorban, ami nem is lenne probléma, csakhogy én szeretnék írni az osztálynak egy operator>>-t is. Viszont ez már eleve egy példány referenciáját veszi át, azaz a konstruktor már lefut azelőtt, hogy beolvasnám az értéket, amit megadnék a konstansnak. Kódban:
#include <iostream>
using namespace std;
class Osztaly
{
private:
const int max;
//van itt más is
public:
Osztaly(const int m) :max(m) {}
//van itt más is
}
istream& operator>>(istream& i,const Osztaly& o)
{
int m;
i >> m;
//???
o.max=m; //nem jó, max már kapott értéket
o=Osztaly(m); //nem jó, akkor az operator=-t kellene úgy megírni, hogy max-ot megváltoztassa
delete o;
Osztaly o=Osztaly(m); //nem jó, o egy referencia, ezt nem tehetem meg vele (tudtommal)
return i;
}
Két workaround is eszembe jutott (max nem konstans, o nem referencia hanem pointer), de ezeket csak akkor választanám, ha tényleg nincs más megoldás.
Ha valakinek van ötlete, ne tartsa magában. Köszönöm!
- 1498 megtekintés
Hozzászólások
Elso! :p
- A hozzászóláshoz be kell jelentkezni
#hup.hu-n imp és nagyz meggyőzött, hogy ez így sehogy nem fog menni, viszont ehelyett proxyosztályt javasoltak. Mivel eddig ez tűnik a legjobb megoldásnak, valószínűleg így fogom csinálni.
--
Don't be an Ubuntard!
- A hozzászóláshoz be kell jelentkezni
<imp> en inkabb azt mondom, hogy a >> legyen ugyanolyan, mint egy copy assignment
<BaT_> mondjuk en is csak egyszer lattam ilyen proxys megoldast, irni meg soha nem irtam
<imp> vagy ne a streamrol olvasd a maxot
<imp> egyebet nem tudok elmondani
<nagyz> +1
- A hozzászóláshoz be kell jelentkezni
De a proxyt is te mondtad. ;)
--
Don't be an Ubuntard!
- A hozzászóláshoz be kell jelentkezni
igen, de ez nem jelenti azt, hogy ilyen insane dolgokat le is programozz:)
- A hozzászóláshoz be kell jelentkezni
altalaban kerulendo a const es ref member.
nem trivialis a msolasuk, ertekadasuk...
- A hozzászóláshoz be kell jelentkezni
Van itt egy olyan ellentmondás, hogy egyrészt te azt mondod, hogy ez a max konstans, tehát az objektum teljes élettartama alatt változatlan, aztán viszont akarsz írni egy fv-t ami megváltoztatja.
Értem én, hogy ez a szerencsétlen fv pont beolvasni szeretne, de ez azon nem változtat, hogy egy meglévő objektumot szeretnél változtatni.
A mutatós megoldás sem jó, hacsak nem mutató referenciát adsz át. (Hogy ez mennyire használhatatlan lenne azt inkább hagyjuk...)
Vagy az operator>>-ról vagy a const-ról le kell mondanod. (Vagy trükköznöd kell egy mutatóval, amit akár egy proxy osztállyal elfedhetsz de attól még felesleges önszopatás.)
Én a const-ot dobnám, de egy Object readObject(iostream&); fv is működhet.
(Vagy static Object Object::read(iostream&);)
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
A const_cast nem jó erre?
Így gondoltam:
#include <iostream>
class A {
const int a;
public:
A(int _a) : a(_a) {}
void setA(int _a) { *(const_cast< int* > (&a)) = _a; }
void print() { std::cout << a << std::endl; }
};
int main()
{
A a(12);
a.print();
a.setA(36);
a.print();
return 0;
}
- A hozzászóláshoz be kell jelentkezni
A const_cast (de a dynamic_cast is) tervezési hibára utal, és csak a legvégső esetben megengedett, illetve illik tőle minél előbb megszabadulni, ha lehet.
- A hozzászóláshoz be kell jelentkezni
Egy szóval sem mondtam, hogy szép, de a konkrét problémára egy megoldási lehetőség.
Megjegyzem, néha kimondottan jól jönne, amikor ugyan a konstruktorban akarsz neki értéket adni, mert változatlan az objektum élete során, de ezt nem tudod megtenni az inicializálási listában, mert a konstruktoron belül mondjuk egy picit bonyolultabb számítás eredményeképpen kapnád meg a kívánt értéket.
- A hozzászóláshoz be kell jelentkezni
Static member function, vagy bármi, amit el tudsz képzelni, de még akkor is inkább legyen nem const a member, minthogy const_cast-olni kelljen; ez nálam nem bocsánatos bűn:)
A const memberek szerintem egyébként is talán csak const T& -ként praktikusak.
- A hozzászóláshoz be kell jelentkezni
Nagyon nem szereted te a constot, látom már.. :)
Pedig a const szép dolog, bár a const_cast tényleg gány.
- A hozzászóláshoz be kell jelentkezni
A const correctness hasznos dolog, és nincs is vele bajom, a const memberváltozó viszont szerintem nem annyira praktikus. A kettő nem ugyanaz.
- A hozzászóláshoz be kell jelentkezni
Bár feltehetően ez amit írtál működne, mivel az a változó valószínűleg konkrétan létezik mint memóriaterület valami elérhető helyen, tudtommal valódi constról lekasztolni a const-t az undefined behavior, nem csak rossz stílus.
----
Hülye pelikán
- A hozzászóláshoz be kell jelentkezni