• 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

Object Storage Arubacloud
0 głosów
480 wizyt
pytanie zadane 27 września 2015 w C i C++ przez radek024 Szeryf (77,160 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,320 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 (77,160 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,320 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 (77,160 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,320 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 (77,160 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,320 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 (344,860 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,320 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 (90,790 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 (77,160 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

+1 głos
1 odpowiedź 112 wizyt
pytanie zadane 22 czerwca 2022 w C i C++ przez Daaa22 Dyskutant (8,250 p.)
0 głosów
1 odpowiedź 192 wizyt
pytanie zadane 13 lutego 2020 w C i C++ przez niezalogowany
0 głosów
1 odpowiedź 121 wizyt
pytanie zadane 7 sierpnia 2016 w Java przez itcloud Gaduła (3,380 p.)

92,536 zapytań

141,377 odpowiedzi

319,452 komentarzy

61,920 pasjonatów

Motyw:

Akcja Pajacyk

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

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...