• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Dodawanie wartości z konstruktorów

0 głosów
248 wizyt
pytanie zadane 27 września 2015 w C i C++ przez radek024 Szeryf (75,200 p.)
#include <iostream>
#include <cstdlib>

using namespace std;

class Wektor
{
	private:
		double a,b;
		string nazwa;
		
	public:
		//Konstruktory - im wiecej tym lepiej
		Wektor()
		{
			a=b=0;
		}
		
		Wektor(double x, double y)
		{
			a=x;
			y=b;
		}
		
		Wektor(string nazwa, double x, double y)
		{
			this->nazwa=nazwa;
			a=x;
			b=y;
		}
		
		Wektor(char znak)
		{
			cout<<"Podaj nazwe: "; cin>>nazwa;
			cout<<"Podaj wspolrzedna a: "; cin>>a;
			cout<<"Podaj wspolrzedna b:"; cin>>b;
		}
		
		void DodajWektory()
		{
			cout<<"Wpisz wartości drugiego wektoru: "<<endl;
			cout<<"Wpisz wspolrzedna a: "; cin>>a;
			cout<<"Wpisz wspolrzedna b:"; cin>>b;
			//tutaj pojawia się problem - jak dodać agrument konstruktora  Wektor(string nazwa, double x, double y) do Wektor(char znak) ?
		}
		//funkcje dodawanie, odejmowanie, mnozenia wektora przez liczbe
		//funkcja pokaz wektor na ekran + menu
	
		
};

int main(int argc, char** argv) {
	//kod do przetestowania ww. klasy

	return 0;
}

 

 

Witam, powoli zaczynam przygodę z obiektowym C++. Jestem w trakcie pojmowania konstruktorów, a kod wyżej to zadanie, które chcę wykonać. Nie wiem jednak, jak dodać wartości z jednego konstruktora do drugiego. Znając życie rozwiązanie jest bardzo proste, a ja za bardzo kombinuję.

Ktoś wie jak to zrobić?

Pozdrawiam, radek024.

2 odpowiedzi

+1 głos
odpowiedź 27 września 2015 przez Patrycjerz Mędrzec (192,440 p.)
edycja 27 września 2015 przez Patrycjerz

Ale w takiej sytuacji będziesz musiał jawnie wywoływać dwa konstruktory, a to nie ma sensu. Radzę ci zrobić konstruktory, które będą wywoływać konstruktor z największą ilością argumentów, poza nim samym, tzn.:

class foo
{
public:
	foo()
	: foo(0, 0, 0) {}
	foo(int a)
	: foo(a, 0, 0) {}
	foo(int a, int b)
	: foo(a, b, 0) {}
	foo(int a, int b, int c)
	: a(a), b(b), c(c) {}
private:
	int a;
	int b;
	int c;
};

 

komentarz 27 września 2015 przez radek024 Szeryf (75,200 p.)
Rozumiem że takie coś działołoby na warunkach? I ten zapis jest odgórnym określeniem ilości konstruktorów dla danej klasy? Po raz pierwszy widzę taki typ :)

PS: Jeżeli chciałbym jednak zrobić to za pomocą wywołania - wydaje się prostsze - jakiego operatora trzeba by użyć? Jak zapisać wywołanie argumentu formalnego z konstruktora?
komentarz 27 września 2015 przez Patrycjerz Mędrzec (192,440 p.)

Konstrukcja:

konstruktor()
: inny_konstruktor()
{
}

to tzw. lista inicjalizacyjna. Oczywiście może w niej być coś innego, niż konstruktor (patrz wyżej). Przeczytaj sobie o niej więcej w internecie.

Możesz także zrobić normalnie w ciele konstruktora:

konstruktor()
{
	inny_konstruktor();
}

ale ogólnie zaleca się stosowanie tego pierwszego sposobu (podobno jest wydajniejszy) i także jego instrukcje są wywoływane przed stworzeniem obiektu - w drugim sposobie po. Dzięki temu można inicjalizować m.in. stałe.

Tego PS trochę nie rozumiem. Napisz to trochę inaczej (a może ja jestem niedouczony smiley).

komentarz 27 września 2015 przez radek024 Szeryf (75,200 p.)

Racja, może trochę przekombinowałem ;). Chcę, aby zmienna x konstruktora Wektor(double x, double y) była równa sumie zmiennej a w Wektor(string nazwa, double x, double y) oraz Wektor(char znak). Jak to zapisać w C++?

komentarz 27 września 2015 przez Patrycjerz Mędrzec (192,440 p.)
edycja 27 września 2015 przez Patrycjerz

Haha... najwyraźniej nie wiesz, na jakich danych operują konstruktory. Więc na danych, które są powiązane z obiektem, dlatego są dostępne wszędzie w klasie (bo masz private). Czy twój pierwszy, czy drugi konstruktor przypisze zmiennej a np. 10, to to a jest ciągle takie samo, gdziekolwiek go nie użyjesz w danym obiekcie.

Chyba rozwiałem twoje wątpliwości.

EDIT: Przepraszam, źle cię zrozumiałem. Takie coś nie ma sensu, ponieważ po pierwsze argumenty konstruktora mają być przesłane przy tworzeniu obiektu (nie nadawane odgórnie), a po drugie chcesz korzystać z wartości, które nie są jeszcze zainicjalizowane (wywołujesz konstruktor i chcesz przekazać mu przez argument zmienną obiektu - nie ma to sensu).

komentarz 27 września 2015 przez radek024 Szeryf (75,200 p.)
Czyli logicznie rzec biorąc, wykonanie działania dodawanie(jak i każdego innego) jest niemożliwe ze wzgledu na to, że dane są chronione. Jako, że sam p. Zelent wskazywał na to, żeby te dane były ustawione jako prywatne, jak mogę zmienić ich wartość?
komentarz 27 września 2015 przez Patrycjerz Mędrzec (192,440 p.)
Oczywiście, nikt ci nie broni, ale ogólnie się przyjęło (ma to swoje wady i zalety), że hermetyzuje się dane klasy i tworzy się dla nich tzw. interfejs, czyli metody, które je obsługują (nadpisanie wartości, zwrócenie wartości i inne). Ale teraz na początku nauki się tym nie przejmuj, bo tylko niepotrzebnie będzie ci to przeszkadzać.
komentarz 27 września 2015 przez adrian17 Ekspert (306,980 p.)

Możesz także zrobić normalnie w ciele konstruktora:
    
konstruktor()
{
    inny_konstruktor();
}

To nie jest prawda, sam spróbuj i zobacz co się stanie:

#include <cstdio>

struct C{
	int x;
	C() {
		x = 5;
	}
	C(int a) {
		C();
	}
};

int main(){
	C c(1);

	printf("%d", c.x);
}

 

komentarz 27 września 2015 przez Patrycjerz Mędrzec (192,440 p.)

Rzeczywiście, podałem trochę brednie, ale chyba gdzieś takie coś zauważyłem i dlatego tak napisałem, nawet nie sprawdzając. Czyli zostaje tylko lista inicjalizacyjna wink

+1 głos
odpowiedź 27 września 2015 przez Benek Szeryf (87,400 p.)

Dodawanie wartości z konstruktorów nie bardzo ma sens. Jedną z ról konstruktora jest inicjalizacja obiektu pewnymi wartościami. Dodawanie obiektów powinno się realizować inaczej, na przykład z użyciem funkcji zaprzyjaźnionych, do czego zapewne niebawem dojdziesz.

Ponadto w kodzie jest kilka złych praktyk. Konstruktor Wektor(char znak) jest dość kontrowersyjny. Zaś w konstruktorze Wektor(string nazwa, double x, double y) użyj innej nazwy dla zmiennej typu string, bo jest taka sama jak nazwa składowej obiektu. W konstruktorze Wektor() wymuszasz automatyczną konwersję typu int na double. W konstruktorze Wektor(string nazwa, double x, double y) masz złe przypisanie y = b; zamiast b = y; Każda składowa klasy powinna mieć osobną deklarację: double a; double b; zamiast double a, b; Funkcje definiowane wewnątrz klasy mają rozwinięcie inline, które jest optymalne dla prostych, niezłożonych funkcji.

komentarz 27 września 2015 przez radek024 Szeryf (75,200 p.)

 Konstruktor Wektor(char znak) jest dość kontrowersyjny.

Tutaj chodziło mi o utworzenie kolejnego konstruktora, co złego w zapisie char znak?

Wektor(string nazwa, double x, double y) użyj innej nazwy dla zmiennej typu string, bo jest taka sama jak nazwa składowej obiektu.

Tutaj zrobiłem to celowo, aby użyć komendy "this. " - dla zapamiętania :)

 

W konstruktorze Wektor() wymuszasz automatyczną konwersję typu int na double.

Jeżeli zamienię 0 na 0.0, nie będzie problemu?

 

Co do dwóch ostatnich nie mam pytań :)

Podobne pytania

0 głosów
1 odpowiedź 117 wizyt
pytanie zadane 13 lutego 2020 w C i C++ przez niezalogowany
0 głosów
1 odpowiedź 86 wizyt
pytanie zadane 7 sierpnia 2016 w Java przez itcloud Gaduła (3,380 p.)
0 głosów
3 odpowiedzi 161 wizyt

86,526 zapytań

135,279 odpowiedzi

300,595 komentarzy

57,276 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...