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

Dobra praktyka inicjalizacji tablicy char w constructorze

VPS Starter Arubacloud
0 głosów
255 wizyt
pytanie zadane 4 kwietnia 2016 w C i C++ przez Fenix Nałogowiec (26,750 p.)
edycja 4 kwietnia 2016 przez Fenix
W jaki sposób inicjalizujecie tablice char w konstruktorze, jeśli nie wiecie jakiej długości przyjdzie?

Pętla for + jakieś sizeof'y żeby sprawdzić długość czy jeszcze jakiś inny pomysł?

2 odpowiedzi

+2 głosów
odpowiedź 4 kwietnia 2016 przez draghan VIP (106,230 p.)
wybrane 5 kwietnia 2016 przez Fenix
 
Najlepsza
1. Nie używam raw-arrays, jeśli nie muszę... Od napisów jest std::string. Od liczb są inne kontenery, jak std::array czy std::vector.

2. Jeśli muszę, pomijam pierwsze zdanie punktu pierwszego.

 

...a od sprawdzenia długości napisu na char[], jest funkcja strlen z nagłówka cstring.
komentarz 5 kwietnia 2016 przez Fenix Nałogowiec (26,750 p.)
No tak oczywiście że są string'i, ale pomagam czasem rozwiązać jakieś zadania studenckie i tam stety czy nie prowadzący często ustalają jasne reguły gry. (tzn. jak robisz coś komuś, to lepiej żeby on już się nie kłócił ani sobie problemów nie robił (bo i po co?), tylko miał to cacy zrobione.
komentarz 5 kwietnia 2016 przez draghan VIP (106,230 p.)
edycja 5 kwietnia 2016 przez draghan

Może czas nauczyć wykładowców, żeby się ogarnęli i zaczęli uczyć dobrych praktyk. :)

Jeśli obiekt ma przechowywać w tablicy char napis, podany w konstruktorze, to robi się to jakoś tak:

#include <cstring>
#include <iostream>

class Foo
{
    char *string;
public:
    Foo(const char *string)
    {
        size_t length = strlen(string);
        this -> string = new char[length+1];
        strcpy(this -> string, string);
    }

    Foo(const Foo &f)
    {
        size_t length = strlen(f.string);
        this -> string = new char[length+1];
        strcpy(this -> string, f.string);
    }

    Foo& operator=(const Foo &f)
    {
        if(&f == this) return *this;

        delete[] this->string;
        size_t length = strlen(f.string);
        this -> string = new char[length+1];
        strcpy(this -> string, f.string);
        return *this;
    }

    ~Foo()
    {
        delete[] string;
    }

    void print() const
    {
        std::cout<<string<<"\n";
    }

    void modify()
    {
        string[0] = 'Z'; // jakaś operacja bez sensu...
    }
};

int main()
{
    char str[] = "Abc";
    Foo bar1(str);

    str[2] = 'C';
    Foo bar2(str);

    Foo bar3("Cba");
    Foo bar4 = bar2;

    bar1.print();
    bar2.print();
    bar3.print();
    bar4.print();

    std::cout<<"Po modyfikacji:\n";
    bar2.modify();
    bar2.print();
    bar4.print();

    std::cout<<"Przypisanie:\n";
    bar4 = bar2;
    bar2.print();
    bar4.print();

    return 0;
}

 

1
komentarz 5 kwietnia 2016 przez maly Nałogowiec (37,190 p.)
Masz mały błąd, dla cstringów trzeba zaalokować więcej pamięci(strlen + 1) i zakończyć tekst zerem('\0').
komentarz 5 kwietnia 2016 przez draghan VIP (106,230 p.)
Masz rację, i to nie taki mały ten błąd. Moje niedopatrzenie. Poprawiam, żeby ktoś się nie sugerował tym potem, dziękuję bardzo. :) +1
0 głosów
odpowiedź 4 kwietnia 2016 przez Patrycjerz Mędrzec (192,320 p.)
Do przechowania tablicy wystarczy wskaźnik (dla tablicy jednowymiarowej) lub wskaźniki (dla tablicy wielowymiarowej).
komentarz 4 kwietnia 2016 przez Fenix Nałogowiec (26,750 p.)
Chodzi mi o stworzenie konstruktora który otrzymuje/zapisuje tablice charów, jaka jest najlepsza praktyka.
komentarz 4 kwietnia 2016 przez Patrycjerz Mędrzec (192,320 p.)
edycja 4 kwietnia 2016 przez Patrycjerz
#include <iostream>

class Klasa
{
public:
	Klasa(char* tablica)
	{
		tablica_ = tablica;
	}
	void wypisz()
	{
		std::cout << tablica_ << std::endl;
	}
private:
	char* tablica_;
};

int main()
{
	char tablica[] = "Ala ma kota";
	Klasa obiekt(tablica);
	obiekt.wypisz();
	std::cin.get();
	return 0;
}

 

komentarz 4 kwietnia 2016 przez draghan VIP (106,230 p.)
Patrycjerz, przemyśl swoje rozwiązanie. ;)
komentarz 4 kwietnia 2016 przez Patrycjerz Mędrzec (192,320 p.)

Chodziło o średnik, czyż nie? wink

1
komentarz 4 kwietnia 2016 przez draghan VIP (106,230 p.)
Nie, o rozwiązanie. W przypadku, który podajesz, kopiujesz tylko wskaźnik, nie wartości. To może powodować przykre konsekwencje, jeśli np. ów wskaźnik pokazywał na tablicę dynamiczną a pamięć została zwolniona.
komentarz 6 kwietnia 2016 przez Patrycjerz Mędrzec (192,320 p.)
Oczywiście, ale mój kod pokazuje jedynie sposób na przesłanie tablicy do klasy - zabezpieczenia oraz słuszność tego rozwiązania pozostawiam w gestii każdego z osobna. Osobiście użyłbym jakiegoś kontenera z biblioteki standardowej, ale jak już wcześniej mówiłem, to jest tylko przykład, w celach edukacyjnych.

Podobne pytania

0 głosów
6 odpowiedzi 1,219 wizyt
pytanie zadane 21 sierpnia 2016 w C i C++ przez newgu123 Początkujący (260 p.)
0 głosów
1 odpowiedź 541 wizyt
pytanie zadane 12 lutego 2016 w C i C++ przez konrad99 Gaduła (4,090 p.)
0 głosów
1 odpowiedź 813 wizyt
pytanie zadane 4 maja 2017 w C i C++ przez seba Dyskutant (8,900 p.)

92,839 zapytań

141,780 odpowiedzi

320,849 komentarzy

62,171 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

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!

...