Referencja referencji w C++

0

Witajcie. Wiem, że tytuł jest dość idiotyczny, ale to mało ważne.
Powiedzmy, że mam taką klasę:

class a
{
int j;
void zmien(int &i);
void zmien2();
};
void a::zmien(int &i)
{
//j = ?
}
void a::zmien2()
{
j = 56;
}

I teraz chciałbym, aby zmienna podana w funkcji 'zmien' po użyciu funkcji 'zmien2' zyskała wartość 56.
Czy jest to możliwe? Jest to mi bardzo potrzebne do pewnego programu, dlatego będę wdzięczny za wszelką pomoc. ;)

0

coś pokręciłeś. nie trzeba robić „referencji do referencji”. co chcesz właściwie uzyskać?

0

Dzięki za szybką odpowiedź.
Chodzi mi jedynie o to, że po podaniu zmiennej jako argument w pierwszej funkcji i po użyciu drugiej funkcji zyska ona nową wartość. Pokaże to na przykładzie kodu:

int i = 0;
zmien(i); // nadal i = 0
zmien2(); // ale już tu i = 56
0

chodzi mu o coś takiego:

int *j;
 
void zmien(int &i)
{
  j = &i;
}
 
void zmien2()
{
  *j = 56;
}
 
int main()
{
  int a = 5;
  zmien(a);
  zmien2();
  std::cout << a; // 56
}

tylko że na referencjach
imo niemożliwe bo referencje są stałe i nie można ich zmieniać w trakcie programu, więc musisz użyć wskaźników tak jak w przykładzie powyżej
ale nie znam c++ zbyt dobrze więc się nie wtrącam ;)

BTW - takie podejście jest złe, nieintuicyjne, wprowadza zamęt, utrudnia optymalizacje i jest sprzeczne z ideą programowania obiektowego

0

@unikalna_nazwa
Nie wiem czemu takie podejść jest złe, ale ja muszę to zrobić i już, bo innej drogi nie mam.
Mam pewną dużą tablice klasę i każdy element tej klasy musi znać swój numer w tablicy, dzięki czemu klasa wie ile ma swoich elementów w programie(i nie tylko) z tym, że kiedy usunę jakiś element klasy, to wtedy licznik który zlicza te wszystkie elementy tablicy niestety nie cofnie się, a chciałbym żeby był na bieżąco. Dodatkowo licznik ten jest na zewnątrz klasy.(bo musi być). Nie wierzę, że możliwości C++ na tym się kończą.

Hmm... Nie jestem pewien czy da się coś wywnioskować z tego, co u góry napisałem. Jeżeli nie, to musicie mi uwierzyć na słowo, że muszę coś takiego mieć w swoim programie i innej opcji nie ma.

0

no to do licznika powinieneś się po prostu odwoływać przez a.licznik za każdym razem zamiast zapamiętywać na zewnątrz jego wartość

i czemu możliwości c++ "kończą się"? możesz w najgorszym przypadku użyć wskaźników - dostałeś działający przykład

0

btw, nie mozesz zamiescic swojego kodu? Łatwiej będzie Ci podsunąć najlepsze rozwiązanie jak sięma przed oczami konkretny kod, a nie przykłądowy :)

0

Nie wiem, czy dobrze rozumiem problem, ale można takie coś zrobić za pomocą konstruktora (lista inicjalizacyjna):

class a
{
	int& j;
	a(int& init) : j(init) {}
	void zmien();
};

void a::zmien()
{
	j = 56;
}

int main()
{
	int var = 0;
	a obj(var);
	zmien(); // a::j == var == 56
	// uwaga!
	var = 666; // a::j == 666
}

W tym wypadku var i j odwołują się do tej samej zmiennej, i jest to połączenie nierozerwalne. Jeśli chcesz zmieniać zmienną, do której odwołuje się j, to tylko na wskaźnikach – polecam smart pointery z C++11, ewentualnie z Boosta, jeśli kompilator nie wspiera nowego standardu.

0
rincewind napisał(a):
class a
{
	int& j;
	a(int& init) : j(init) {}
	void zmien();
        void zmien2(int &init); // dodano
};

I właściwie można dopisać:

void zmien2(int &init)
  {
   (reinterpret_cast<int*>(this))=&init;
  }

Użycie:

int main()
  {
   int var1 = 0,var2 = 0;
   a obj(var1); // &a::j == &var1
   zmien(); // a::j == var1 == 56
   zmien2(var2); // &a::j == &var2
   zmien(); // a::j == var2 == 56
   return 0;
  }
0

Pojawia mi się błąd:

C2512: 'a' : no appropriate default constructor available
0

Bo nie zrobiłeś domyślnego konstruktora i niezbyt łatwo będzie go zrobić.

0
Franeks napisał(a):

Pojawia mi się błąd:

C2512: 'a' : no appropriate default constructor available

ale nie używaj na poważnie kodu dragona bo to zło niekonieczne ;)
użyj normalnych wskaźników

a imho potrzeba Ci dokładnie odwrotnego podejścia:

#include <iostream>
 
using namespace std;
 
class klasa
{
        int counter;
        public:
 
        int& getCounter()
        {
                return counter;
        }
 
        void licz()
        {
                counter ++;
        }
};
 
int main()
{
        klasa a;
        int &licznik = a.getCounter();
 
        cout << licznik << endl; // 0
 
        a.licz();
 
        cout << licznik << endl; // 1 => klasa::counter = 1
}

w tym podejściu proponuję stworzyć dodatkową strukturę Counter, i stworzenie prywatnego pola licznika, po czym zaprzyjaźnić klasę Counter z główną
w ten sposób uzyskasz licznik "tylko do odczytu" dla programu głównego który może być modyfikowany przez tę klasę

jednocześnie licznik jest "na zewnątrz" czyli tak jak chciałeś (choć nie wiem czemu)

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