Kontruktor zwracający NULL

0

Witam.

Mam taki problem z inicjalizacją klasy. Powiedzmy, że mam taki przykładowy kod:

class Klasa{
//jakies zmienne
public:
	Klasa();
	~Klasa();
};

Klasa::Klasa(){
	if(wazna_operacja_dla_istnienia_obiektu){
		//dalsza inicjalizacja
	}else{	//coś poszło nie tak
		//Tutaj chciałbym zwrócić nie opiekt tylko wartość NULL
	}
}

int main(int argc,char **argv){
	Klasa a;	//wszystko poszlo ok i w zmiennej klasy a jest obiekt
	Klasa b;	//coś poszło nie tak i chciałbym aby tutaj był NULL
	return 0;
}
 

Chciałbym uzyskać coś takiego, że w przypadku gdy klasa nie może się zainicjować to zwraca jako swój obiekt (obiekt pusty) i nie tworzy się na stosie czy na czym tam przyjdzie.
Jest na to jakiś sposób?

0

'Konstruktor nic nie zwraca. Nie moze zwrocic null, a rzucanie wyjatkiem w konstruktorze to zly pomysl!

Po prostu zrob pole "valid" i jezeli

valid == false

to obiekt jest zle stworzony'
</del>
poczytaj tutaj
https://isocpp.org/wiki/faq/exceptions#ctors-can-throw

1

Ja bym w takiej sytuacji zrobił sobie np. Factory dla tych obiektów i zwracał sobie np. optionala z tego factory.

0

jeśli chcesz do jakiejś zmiennej wpisać NULL to tak mi sie wydaje ze to musi byc wskaźnik, czyli: Klasa* a = new Klasa(), ale tak czy siak obiekt i tak zostanie utworzony, bo konstruktor tak działa, tworzy obiekt niczego nie zwracając, to operator new zwraca obiekt typu Klasa. Jeżeli coś poszło nie tak i chcesz pozbyć się tego obiektu to możesz stworzyć pole klasy valid jak napisał Fasadin, w konstruktorze przypisac mu wartość odpowiadająca że coś jest źle i potem w kodzie odczytać tą wartość, jeżeli jest źle to do wskaźnika a przypisujesz wartość NULL, chociaż nie mam pojęcia do czego ci takie kombinacje potrzebne.

0

Faktory oraz Builder zapewne(sprawdzanie obiektu po utworzeniu) , odpadają, ponieważ rozwiązanie musi być maksymalnie proste. Wyjątki są w moim przypadku najlepszym wyjściem. Dziękuję wszystkim za odpowiedzi.

1
czaffik napisał(a):

jeśli chcesz do jakiejś zmiennej wpisać NULL to tak mi sie wydaje ze to musi byc wskaźnik, czyli: Klasa* a = new Klasa(), ale tak czy siak obiekt i tak zostanie utworzony, bo konstruktor tak działa, tworzy obiekt niczego nie zwracając, to operator new zwraca obiekt typu Klasa.

Ale może być funkcja statyczna zwracająca wskaźnik. Konstruktor może być wtedy prywatny.

#include <iostream>
#include <cassert>
using namespace std;

class Foo
{
	public:
		static Foo* Create(bool seriously)
		{
			if (seriously)
				return new Foo();
			else
				return nullptr;
		}
	private:
		Foo()
		{
			cout << "konstruktor" << endl;
		}
};


int main()
{
	// Foo a;  /* błąd */

	// auto b = new Foo(); /* błąd */

	auto c = Foo::Create(true);
	assert(c != nullptr);

	auto d = Foo::Create(false);
	assert(d == nullptr);

	delete c;
}

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