Konstruktor domyślny

0

Hej! Robię zadanko na studia z obiektówki. Prosta sprawa, natomiast odrobinę się chyba sam zgubiłem co nie działa (a właściwie dlaczego). Czy jest tutaj jakaś dobra dusza, która pomoże rozwiązać problem? Nie jestem wirtuozem c++ niestety :/

Mam kilka plików, natomiast najważniejsze są 3, na których pracuję. Worker.h, Secretary.h i Main.cpp.

Problem polega na tym, że muszę wyświetlić dla każdej klasy konstruktor albo domyślny, albo sparametryzowany, albo kopiujący, który dziedziczy z innego konstruktora. U mnie wygląda to tak: konstruktor Worker odpawiada ogólnie za wszystkich pracowników, nadaje im ID i zwiększa licznik +1 żeby potem w destruktorze zmniejszyć go o -1. Działa mi wszystko na konstruktorach sparametryzowanych, natomiast próbując wrzucić konstruktor domyślny zaczynają mi się sypać błędy.

Worker.h

#pragma once
#include <iostream>

using namespace std;

int counter = 0;
int maxuid = 0;

class Worker
{

protected:
	int uid;
	double cash;
	string name;
	string surname;

public:
	//KONSTRUKTOR DOMYSLNY
	Worker(double cash = 2000, string name = " Pracownik ", string surname = " ")
	{
		cout << " Konstruktor domyslny " << endl << endl;
		this->cash = cash;
		this->name = name;
		this->surname = surname;
	};

	//KONSTRUKTOR SPARAMETRYZOWANY
	Worker(double cash, string name, string surname) : name(name), surname(surname), cash(cash), uid(maxuid)
	{
		maxuid++;
		counter++;
		cout << " KONSTRUKTOR sparametryzowany " << endl << endl;
		cout << " UID: " << maxuid << endl;
	};

	//DESTRUKTOR
	~Worker()
	{
		cout << " Dzialjacy DESTRUKTOR " << endl;
		cout << " Licznik PRZED destrukcja: " << counter << endl;
		counter--;
		cout << " Licznik PO destrukcji:    " << counter << endl << endl;
		cout << " -----------------------------" << endl << endl;
	};

	double getCash()
	{
		return cash;
	}

	void setCash(double cash)
	{
		this->cash = cash;
	}

	string getName()
	{
		return name;
	}

	void setName(string name)
	{
		this->name = name;
	}

	string getSurname()
	{
		return surname;
	}

	void setSurame(string surname)
	{
		this->surname = surname;
	}
};
Secretary.h
#pragma once
#include "Worker.h"
#include "RandCash.h"

class Secretary : protected Worker
{
	string ifexperience;
	bool experience = 1;
	public:
// TAKI ZAPIS NIE DZIAŁĄ, NATOMIAST NIE JESTEM PEWNY JEGO POPRAWNOSCI
		Secretary() : Worker()
		{
			cout << " z klasy secretary " << endl << endl;
		};

		Secretary(double cash, string name, string surname) : Worker(cash * RandCost(1, 3), name, surname)
		{
			experience = RandCost(1, 2);
			if (experience == true)
			{
				cash = cash + 1500 * RandCost(1, 3);
				ifexperience = "TAK";
			}
			else
			{
				ifexperience = "NIE";
			}

			cout << name << " " << surname << endl;
			cout << " Czy posiada doswiadczenie? " << ifexperience << endl;
			cout << " W sumie zarabia: " << cash << " brutto" << endl << endl;
		}
};
#include <iostream>
#include <ctime>
#include <windows.h>
#include "Boss.h"
#include "ItSpecialist.h"
#include "Secretary.h"

using namespace std;

int main()
{
	srand(time(NULL));
	Boss* boss = new Boss(6000, " Marek", "Goa");
	delete boss;
	Sleep(1000);
	Secretary* secretary = new Secretary(6000, " Czarek", "Gob");
	delete secretary;
	Sleep(1000);
	ItSpecialist* itspecialist = new ItSpecialist(6000," Darek", "Goc");
	delete boss;
	Sleep(1000);

 // BEZ TEGO DZIALA
	Secretary* sec = new Secretary();
	delete sec;
	Sleep(1000);

	getchar();
	return 0;
}

Dodałem w pliku Secretary i Main komentarze do miejsc, które psują program. Zdaję sobie sprawę, że problem najpewniej wynika z zapisu. Niestety moja wiedza tutaj się urywa wraz z pomysłami. :/

0

Problemem jest to, że w jednym przykładzie nie masz konstruktora bezargumentowego, a w drugim już masz i chcesz dziedziczyć po tym poprzednim. Musisz zdefiniować dla klasy bazowej konstruktor bezargumentowy, jeśli chcesz po nim dziedziczyć

0

public:

Worker()
{
};

Dodaj coś takiego.

1

Możesz też napisać zamiast tego

  	if (experience == true)
  	{
  		cash = cash + 1500 * RandCost(1, 3);
  		ifexperience = "TAK";
  	}

to:

  	if (experience)
  	{
  		cash = cash + 1500 * RandCost(1, 3);
  		ifexperience = "TAK";
  	}
0

Hej, dzięki za odpowiedź! :) Nie jestem pewny czy dobrze zrozumiałem, pozwolę sobie wrzucić co mi się w głowie zrodziło.
Innymi słowy w pliku Worker.h powinienem wrzucić deklarację?:

Worker() {}

Kurcze, wydawało mi się, że jeśli mam w pliku Worker konstruktor z wpisanymi wartościami to po użyciu go gdzieś na zasadzie właśnie

		Secretary() : Worker()
		{
			cout << " z klasy secretary " << endl << endl;
		};

przypiszą się od razu wartości domyślne. Jak najeżdżam na Worker(), wyświetla mi podpowiedź, że jest to właśnie ten konstruktor domyślny, z którego chciałem przenieść wartości

0

Wyrzuca mi wciąż błędy:

1>Worker.h(31,51): error C2535: „Worker::Worker(double,std::string,std::string)”: Funkcja składowa już zdefiniowana lub zadeklarowana
1>Worker.h(22): message : zobacz deklarację „Worker::Worker”
1>Secretary.h(10,23): error C2668: "Worker::Worker": niejednoznaczne wywołanie przeciążonej funkcji
1>Worker.h(22,2): message : może to być „Worker::Worker(double,std::string,std::string)”
1>Worker.h(19,2): message : lub       "Worker::Worker(void)"
1>Secretary.h(11,1): message : podczas próby dopasowania listy argumentów "()"
1>Main.cpp(12,12): warning C4244: "argument": konwersja z "time_t" do "unsigned int", możliwa utrata danych
1>Kompilowanie projektu „Pointers.vcxproj” wykonane — NIEPOWODZENIE.
1

To się nie skompiluje, bo robisz tutaj redeklarację:

Worker(double cash = 2000, string name = " Pracownik ", string surname = " ")

Worker(double cash, string name, string surname)

W skrócie to jednego z powyższych musisz się pozbyć.

Tego nie musisz pisać (: Worker()):
Secretary() : Worker()

Jeśli wywołasz konstruktor domyślny z klasy dziedziczącej to automatycznie wywoła się też konstruktor domyślny z klasy głównej (jeśli taki istnieje, inaczej będzie błąd kompilacji). Nie musisz sam wskazywać konstruktora.

Worker() {} To jest definicja też, nie tylko deklaracja.

Popraw te błędy i sprawdź co się dalej dzieje z kodem.

I jeszcze proponuję zmienić język w IDE na angielski, bo komunikaty kompilatora po polsku będą Ci wszystko utrudniać, choćby w "goglowaniu".

1

Nie stosuj zmiennych globalnych int counter = 0;. Zamiast tego włącz je do klasy Worker jako statyczne.
Używając C++ 17 można pokusić się o taką tego implementację.

#include <iostream>
#include <memory>

using namespace std;

struct WorkerData
{
    double salary {0};
    string name;
    string surname;
};

class Worker
{

private:

    static inline int instances {0};
    static inline int currentid {0};

protected:

    int uid;
    WorkerData workerData;

public:

    Worker( WorkerData workerData )
    : workerData {workerData}
    {
        ++instances; uid = currentid++;
    }

    virtual ~Worker(){ --instances; }

    int getUiD() const { return uid; }
    WorkerData get() const { return workerData; }

    static int getInstances() { return instances; }
};

class Secretary : public Worker
{

public:

    Secretary( WorkerData workerData = {} )
    : Worker( workerData )
    {
    }
};

int main()
{
    Secretary Marry( { 2500 , "Marry" , "Pensil" } );
    Secretary Noname {};
    cout << Marry.get().name << "\n";
    cout << Noname.get().name << "\n";

    {
        auto Anna = make_unique<Secretary>( WorkerData{ 5200 , "Anna" , "Ballpen" } );
        auto Jane = make_unique<Secretary>( WorkerData{ 7500 , "Jane" , "Starless" } );
        auto John = make_unique<Worker>( WorkerData{ 1500 , "John" , "Doe" } );
        cout << Worker::getInstances() << "\n";
        cout << "Jane has uid = " << Jane->getUiD() << "\n";
    }

    cout << Worker::getInstances() << "\n";

    return 0;
}
0

Dzięki śliczne Tomasz za uwagi. Właśnie wiem, że lepiej zrobić zmienne statycznie aniżeli globalnie, natomiast zdawałem sobie też sprawę, że trochę byłoby kombinowania z samym przebudowaniem. Zastanawiam się jednak nad zasadnością użycia struktury. Bo z tego co pamiętam w c++ klasę od struktury różni głównie to, że struktura jest publiczna, gdzie klasa zachowuje prywatność. W każdym razie, jeszcze raz dziękuję za pomoc Panowie. Przydała się i przy okazji dowiedziałem się kilku ciekawych rzeczy. :)

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