Inicjalizacja tablicy obiektem

0

Proszę o pomoc, bo nie rozumiem w jaki sposób mam tego dokonać

ptabB = new Budynek[lbudynkow]("a",1,1); //<--- POLU ptabB przydzielić dynamicznie pamięć dla tablicy o rozmiarze l_budynkow
 #include <iostream>
#include <string.h>
using namespace std;

class Budynek{
    char* adres;
    int l_pieter;
    int l_mieszkan;

public:
    Budynek(char* a_adres, int pieter, int mieszkan);
    ~Budynek();
    Budynek operator=(Budynek &prawa);
    void Wpisz();
    int LiczbaMieszkan() const;
};

class Osiedle{
protected:
    const int nrSpoldzieni;
    Budynek *ptabB;
    int l_budynkow;

public:
    Osiedle(int lbudynkow, int nspoldzielni);
    ~Osiedle();
};

Osiedle::Osiedle(int lbudynkow, int nspoldzielni)
    :nrSpoldzieni(nspoldzielni), l_budynkow(lbudynkow){
    ptabB = new Budynek[lbudynkow]("a",1,1); //<--- POLU ptabB przydzielić dynamicznie pamięć dla tablicy o rozmiarze l_budynkow
}

Budynek::Budynek(char* a_adres, int pieter, int mieszkan){
    adres = new char[strlen(a_adres)+1];
    strcpy(adres,a_adres);

    l_pieter=pieter;
    l_mieszkan=mieszkan;

    cout<<"Stworzylem obiekt o adresie: "<<this->adres<<endl;
}
Budynek::~Budynek(){
    delete [] adres;
}
Budynek Budynek::operator=(Budynek &prawa){
    if(this!=&prawa){
        adres = new char[strlen(prawa.adres)];
        strcpy(adres,prawa.adres);
        l_pieter = prawa.l_pieter;
        l_mieszkan = prawa.l_mieszkan;

        cout<<endl<<"Adres: "<<this->adres<<endl;
        cout<<"l_pieter: "<<this->l_pieter<<endl;
        cout<<"l_mieszkan: "<<this->l_mieszkan<<endl;

        return *this;
    }else{cout<<"nie mozna przypisac do siebie samego"<<endl;}

}
void Budynek::Wpisz(){
    char* temp = new char [100];
    cout<<endl<<"Podaj adres"<<endl;
    cin>>temp;
    cout<<"Podaj l_pieter"<<endl;
    cin>>l_pieter;
    cout<<"Podaj l_mieszkan"<<endl;
    cin>>l_mieszkan;
}

int Budynek::LiczbaMieszkan() const{
    return this->l_mieszkan;
}



int main(){
    Budynek a1("nazwa",1,1);
    Budynek a2("st",2,2);

    a1=a2;

    a1.Wpisz();

    cout<<endl<<"Liczba mieszkan: "<<a1.LiczbaMieszkan()<<endl;


    return 0;
}
3

nie mozna wywolywac konstruktorow gdy tworzysz dynamiczna tablice. Zostanie jedynie domyslny konstruktor wywolany (nie wiem czy zmienili to w c++11 [raczej nie])
musialbys zrobic osobna metode dla ktorej przydzielasz innym pamiec, ale czemu tutaj nie skorzystasz z std::string?

do tego widac ze nie do konca potrafisz dobrze manipulowac tablica charow, duzo prosciej i latwiej CI bedzie korzystac z std::string

edit. Zgodnie z tym co twonek napisal powinienes uzyc std::vector + std::string

3

Skoro nie masz bezparametrowego konstruktora, to nie możesz używać new[]. Gdybyś używał std::vector to mógłbyś to rozwiązać czymś w stylu

vector<Budynek> budynki(l_budynkow, Budynek("a",1,1));
0

Uczę się do egzaminu i nie mogę ogarnąć tego przydziału pamięci dla tablicy. Załączam test który rozwiązuje (sorry za jakość). Myślę że to nie może być trudne, na pewno jest jakiś prosty i szybki sposób na zrobienie tego.

"1. Konstruktor z dwoma argumentami typu int lbudynkow, int nspoldzielni majacy za zadanie zainicjalizowac wszystkie pola skladowe (pole nrSpoldzielni na podstawie argumentu nspoldzielni, pole l_budynkow na podstawie argumentu lbudynkow, POLU PTABB PRZYDZIELIC DYNAMICZNIE PAMIEC DLA TABLICY O ROZMIARZE l_budynkow"

PS. Vector nie mogę użyć.

0

TREŚĆ:

Zdefiniuj klase o nazwie Budynek o następujących polach składowych umieszczon w części prywatnej:
char* adres;
int l_pieter;
int l_mieszkan;

W części publicznej zadeklaruj następujace metody (definicje muszą znajdować się poza klasą):

  1. Konstruktor z trzema argumentami domyślnymi: pierwszy typu char* inicjalizujący pole adres poprzez dynamiczna alokację pamięci i skopiowanie zawartości argumentu do tego pola, drugi i trzeci typu int inicjalizujące odpowiednio pola l_pieter i l_mieszkan.
  2. Destruktor zwalniajacy przydzieloną pamięć.
  3. Kaskadowy, zabezpieczony przed przypisaniem obiektu do samego siebie, operator=
  4. Metode void Wpisz() wprowadzającą ze standardowego strumienia wejściowego (cin)dane potrzebne do ustawienia wszystkich pól składowych klasy.
  5. Metodę int LiczbaMieszkan()const zwracającą wartość pola l_mieszkan

Zdefiniuj klase o nazwie Osiedle o następujących polach składowych umieszczonych w części chronionej:

const int nrSpoldzielni;
Budynek *ptabB; //wskaznik do tablicy wszystkich budynkow na osiedlu
int l_budynkow; //rozmiar tablicy - liczba budynkow

W czesci publicznej zadeklaruj metody (definicje poza klasą):
1. Konstruktor z dwoma argumentami typu int lbudynkow, int nspoldzielni majacy za zadanie zainicjalizowac wszystkie pola skladowe (pole nrSpoldzielni na podstawie argumentu nspoldzielni, pole l_budynkow na podstawie argumentu lbudynkow, POLU
PTABB PRZYDZIELIC DYNAMICZNIE PAMIEC DLA TABLICY O ROZMIARZE l_budynkow

  1. Destruktor zwalniający pamiec.
  2. Konstrukto kopiujący inicjalizujący wszystkie pola na podstawie argumentu.
  3. Kaskadowy, zabezpieczony przed przypisaniem obiektu do samego siebie operator=
  4. Metodę void wpisz() która dla wszystkich obiektów z tablicy ptabB wywołuję metodę Wpisz() z klasy Budynek
  5. Metode void Wypisz()const wtpisującą na ekran informacje o liczbie wszgstkich budynkow oraz sumy wszystkich mieszkan budynkow znajdujacych sie w tablicy ptabB.
1

Aby tylko zaalokować pamięć dla obiektu o szczegolnym typie, użyj: http://en.cppreference.com/w/cpp/memory/allocator
potem wypełni w pętli obiektami.

BTW: gcc'owa implmentacja vectora korzysta właśnie z allocatora.

Co do samego zadania to jest ulatwione: masz napisac konstuktor z parametrami domyslnymi co czyni go samego domyślnym, potem: http://stackoverflow.com/questions/8462895/how-to-dynamically-declare-an-array-of-objects-with-a-constructor-in-c

0
allocator<Budynek> bb;
    ptabB=bb.allocate(l_budynkow);
    for(int i=0; i<l_budynkow; i++){
        ptabB[i] = new char Budynek();
    } 
<ort> C:\Users\Damian\Desktop\wggg\poprawka.cpp||In constructor 'Osiedle::Osiedle(int, int)':| C:\Users\Damian\Desktop\wggg\poprawka.cpp|34|error: two or more data types in declaration of 'type name'| C:\Users\Damian\Desktop\wggg\poprawka.cpp||In function 'int main()':| C:\Users\Damian\Desktop\wggg\poprawka.cpp|83|warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]| C:\Users\Damian\Desktop\wggg\poprawka.cpp|84|warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]| == Build failed: 1 error(s), 2 warning(s) (0 minute(s), 0 second(s)) ===|</ort> ----------------
2

No, ale masz przecież

  1. Konstruktor z trzema argumentami domyślnymi
    Chyba tego nie doczytałeś.

Czyli robisz takie cuda:

class Budynek{
 ...
public:
    Budynek(char* a_adres = nullptr, int pieter = 10, int mieszkan = 100);
...
};

I potem możesz tworzyć normalnie sobie tablicę.

ptabB = new Budynek[lbudynkow];
0

Dziękuję za pomoc lecz nadal mam jakiś błąd

 
 #include <iostream>
#include <string.h>
using namespace std;

class Budynek{
    char* adres;
    int l_pieter;
    int l_mieszkan;

public:
    Budynek(char* a_adres="", int pieter=1, int mieszkan=1);
    ~Budynek();
    Budynek operator=(Budynek &prawa);
    void Wpisz();
    int LiczbaMieszkan() const;
};

class Osiedle{
protected:
    const int nrSpoldzieni;
    Budynek *ptabB;
    int l_budynkow;

public:
    Osiedle(int lbudynkow, int nspoldzielni);
    ~Osiedle();
};

Osiedle::Osiedle(int lbudynkow, int nspoldzielni)
    :nrSpoldzieni(nspoldzielni), l_budynkow(lbudynkow){
    ptabB = new Budynek[l_budynkow];
}

Budynek::Budynek(char* a_adres="", int pieter=1, int mieszkan=1){
    adres = new char[strlen(a_adres)+1];
    strcpy(adres,a_adres);

    l_pieter=pieter;
    l_mieszkan=mieszkan;

    cout<<"Stworzylem obiekt o adresie: "<<this->adres<<endl;
}
Budynek::~Budynek(){
    delete [] adres;
}
Budynek Budynek::operator=(Budynek &prawa){
    if(this!=&prawa){
        adres = new char[strlen(prawa.adres)];
        strcpy(adres,prawa.adres);
        l_pieter = prawa.l_pieter;
        l_mieszkan = prawa.l_mieszkan;

        cout<<endl<<"Adres: "<<this->adres<<endl;
        cout<<"l_pieter: "<<this->l_pieter<<endl;
        cout<<"l_mieszkan: "<<this->l_mieszkan<<endl;

        return *this;
    }else{cout<<"nie mozna przypisac do siebie samego"<<endl;}

}
void Budynek::Wpisz(){
    char* temp = new char [100];
    cout<<endl<<"Podaj adres"<<endl;
    cin>>temp;
    cout<<"Podaj l_pieter"<<endl;
    cin>>l_pieter;
    cout<<"Podaj l_mieszkan"<<endl;
    cin>>l_mieszkan;
}

int Budynek::LiczbaMieszkan() const{
    return this->l_mieszkan;
}



int main(){
    Budynek a1("nazwa",1,1);
    Budynek a2("st",2,2);

    a1=a2;

    a1.Wpisz();

    cout<<endl<<"Liczba mieszkan: "<<a1.LiczbaMieszkan()<<endl;


    return 0;
}


||In constructor 'Osiedle::Osiedle(int, int)':|
|31|warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]|
|34|error: default argument given for parameter 1 of 'Budynek::Budynek(char*, int, int)' [-fpermissive]|
|11|error: after previous specification in 'Budynek::Budynek(char*, int, int)' [-fpermissive]|
|34|error: default argument given for parameter 2 of 'Budynek::Budynek(char*, int, int)' [-fpermissive]|
|11|error: after previous specification in 'Budynek::Budynek(char*, int, int)' [-fpermissive]|
|34|error: default argument given for parameter 3 of 'Budynek::Budynek(char*, int, int)' [-fpermissive]|
|11|error: after previous specification in 'Budynek::Budynek(char*, int, int)' [-fpermissive]|
||In function 'int main()':|
|78|warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]|
|79|warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]|
||=== Build failed: 6 error(s), 3 warning(s) (0 minute(s), 0 second(s)) ===|
 
0
adres = new char[strlen(a_adres)+1];
...
adres = new char[strlen(prawa.adres)];

Może zrobisz jednak poprawną metodę statyczną?

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.