A const_cast-ot ebben a formában nem veszélyes használni?
Írni akarok egy pointer tömböt, ami eltárol constra és nem constra vonatkozó adatokat is, de ezt egy tömbbe csak úgy lehet megoldani, ha a non-const const konverziós tömböt használok, de ebben az esetben a nem const adatokat nem tudnám a tömbön keresztül kezelni. Ezért akarok CSAK az eredetileg nem const adatokra const_castot alkalmazni abban az esetben, ha változtatni akarnám az értékét, ezt természetesen egy osztály szabályozná amiben benne lenne a tömb is.
Az alapötlet valahogy így nézne ki:
#include <iostream>
using namespace std;
int main()
{
int const ** arr = new const int*[4];
int a = 10;
const int b = 20;
int* c = new int(30);
int const* d = new const int(40);
arr[0] = &a;
arr[1] = &b;
arr[2] = c;
arr[3] = d;
cout << &a << endl;
cout << &b << endl;
cout << c << endl;
cout << d << endl;
for (int i = 0; i<4; i++)
cout << "Memory address: " << arr[i] << "\tValue: " << *arr[i] << endl;
return 0;
}
Ugye arr[0] = 1000-re most hibát dobna, de eredetileg ez nem const, ezért azt const_castolnám, az eredetileg const adatokat viszont nem.
Tudom, hogy sok std megoldás lenne erre a problémára (pl. vektor), de egy egyedit szeretnék, személyre szabottat egy bizonyos problémához.
Amennyiben az érték eredetileg nem konstans, akkor ezzel nyerném ki:
*(const_cast<int*>(arr[0])) = 100;
Amennyiben konstans, nem engedném ezt lefutni rajta.
Nem ideális, mert honnan tudod, hogyha változik a nem konstans értéke, nem csinál relokációt a futás során.
Ebben az esetben akár processen kívülre is kerülhet
a pointer tömböd eleme, (ugye az nem frissül) és jön
a klasszikus 0xC0000005 hiba.
"Nem ideális, mert honnan tudod, hogyha változik a nem konstans értéke, nem csinál relokációt a futás során."
Ezt hogy érted, miért csinálna relokációt? Bocs, ha hülyeséget kérdezek, de amatőr/hobbi szinten programozgatok csak saját célra.
Igazából pár megoldást próbáltam már.
Volt, ami másolatot készített az elemről, és azt tárolta a tömb, ami nekem problémás lenne, mert objektumokkal dolgozok, és pl. 1000 nagy memóriaigényű objektumnál nem örülnék, ha 1000 ugyanolyan létrejönne, már csak azért sem, mert akkor 1000x menne végbe konstruktorhívás.
Ezért maradtam a memóriacím tárolásnál, viszont felmerült a probléma, hogy mi van, ha const.
A memóriacímnél egy problémát találtam, ha megszűnik az objektum, akkor a tömbön keresztül felül tudom írni a megszűnt objektum helyét, ami fatális hibákhoz vezethet, de pont emiatt lesz egy Copy metódus is arra az esetre, ha például a stackről akarok adatot eltárolni, amely megszűnne az adott függvény végén.
Ez úgy nézne ki, hogy annak a másolatát dinamikusan létrehozná, és azt a memóriacímet másolnám a tömbbe.
a = func(a);
itt simán megteheti, hogy az eredeti "a" marad, függvény
visszatérési értékének foglal helyet, majd az "a" pointer-
jét módosítja az új helyre. A régi "a" meg bizonytalan.
Főleg ha "a" objektum.
Nem kell konstruktort meghívnia.
Egyszerűbb lenne külön eltárolnod, melyik a konstans,
egy sima byte tömbben.
Pointeres dolgok mindig is szépek voltak, és irtó
könnyű rajtuk elhasalni :)
Csak akkor nem hív meg konstruktort, ha előtte már a tömb elemeire előre meghívta, utána meg operator=-vel veszi át az adatot, de ezt se úszod meg függvény meg extra konstruktor nélkül, ha csak nem mutatózol.
Viszont már rájöttem hogy lesz:
Tagfüggvényen keresztül lehet létrehozni majd objektumot dinamikusan, amit eltárol egy privát tömb, így ehhez az adathoz csak tagfüggvény által lehet hozzáférni, mellesleg csak egyszer futna le konstruktor, amikor létrehozom, tárolásnál már csak a memóriacímet kapja meg, kilépésnél a destruktor hívja meg a tömb összes elemére a delete-t, meg külön egy delete függvény, ha esetleg egy adatot törölni akarunk. Ezen még elgondolkodok, mert lehet a láncolt lista az elem törlésre jobb megoldás.
Ez a lehető legbiztonságosabb megoldása a problémámnak, ami nem is emészt fel sok erőforrást, csak azt gondoltam, hogy megírom hozzá a saját személyre szabott dinamikusan növekvő tömbömet, amit több helyre felhasználhatok.
Bár főként delphiben/pascalban dolgozok, nálam így néz
ki a dolog:
constructor hív egy RegisterCustomObject nevű függvényt,
amiben paraméterként megadom az új generált objektum (vagy
akármi) pointerjét. Ez beteszi egy listába (thread-safe)
Program futás végén ellenőrzi, hogy az adott listában még
élő objektumok vannak-e (van UnregisterCustomObject-em is)
ha igen, meghívja a destruktort, persze lista elejéről
kezdve, nehogy később generált object behúzódjon valamelyik
előzőhöz (ugye GUInál elementek alárendelődnek, destruktor
azokat is kilövi).
A listához hozzáférek, viszont függvény adja vissza a
pointert, ami pluszba ellenőrzi, hogy a memóriacím, ami
el van tárolva, helyes-e (itt is jó példa a GUI, pilla-
natok alatt újragenerálja magának pl a button/label stb,
és akkor már más pointer lesz), ha igen, akkor visszaadja,
ha nem, akkor nil/null a visszatérés, erre ott az assert.
Kapcsolódó kérdések:
Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!