Uživatelské nástroje

Nástroje pro tento web


prog_cpp

Toto je starší verze dokumentu!


Základy C++

Třídy

  • třida je obdoba struktury. V C++ lze dokonce psát třídy s funkcemi :)
  • při definici se používá viditelnost
    • private - přístupné pouze pro třídu.
    • protected - přístupné pro třídu a potomky třidy.
    • public - přístupné pro všechny
class user {
  private:
    int age;
    string name;
    ..
  public:
    void setAge(int new);
}
  • třída má konstruktor a desktruktor
  • objekt = dynamická/statická instance třídy
  • pokud ve třídě máme nějakou const položku, musíme ji inicializovat v konstruktoru, jinak to nejde
class MyClass {
 
  private:
    const int number;        // deklarace privatni konstantni promenne
    MyClass():number(10) {}  // konstruktor s definici promenne
 
}
  • static const se inicializuje takto
class MyClass {
 
  private:
    static const int number;        // deklarace
}
 
const int MyClass::number = 10;     // definice

dědičnost

  • třída dědí vše od svého předchůdce
  • při deklaraci podřazené třídy se specifikuje, jakým způsobem namapovat rodičovskou třídu
    • zápis class Dog : public Animal - co je public u rodiče, je i u potomka
    • zápis class Dog : protected Animal - co je public u rodiče, je u potomka jako protected
    • zápis class Dog : private Animal - co je public u rodiče, je u potomka jako private
  • virtual
    • definuje tzv pozdní vazbu (až při běhu).
    • Někdy není v době překladu jasné, jestli se má zavolat metoda podtřídy nebo nadtřidy.
    • Klíčové slovo virtual tento problém řeší až při běhu.
    • Příklad problému bez virtual:
class Animal {
  public:
    void eat() { std::cout << "I'm eating generic food."; }
}
 
class Cat : public Animal {
  public:
    void eat() { std::cout << "I'm eating a rat."; }
}
 
//this can go at the top of the main.cpp file
void func(Animal *xyz) { xyz->eat(); }
 
Animal *animal = new Animal;
Cat *cat = new Cat;
 
animal->eat(); // outputs: "I'm eating generic food."
cat->eat();    // outputs: "I'm eating a rat."
 
func(animal) // outputs: "I'm eating generic food."
func(cat)    // outputs: "I'm eating generic food."
  • pro opravu stačí předělat metodu eat u base třídy na virtuální
class Animal {
  public:
    virtual void eat() { std::cout << "I'm eating generic food."; }
}
  • využívá se to pro definici něčeho jako rozhraní/interface.
    • pokud podtřída má nějakou metodu, kterou nadtřída nemá, nelze tuto metodu z nadtřídy zavolat, přestože v objektu nadtřídy máme uložen objekt podtřídy, který tuto metodu má.
    • zkrátka, používá se pro případy, kdy potřebujeme definovat u nadtřídy metodu, která v ni není implementovaná
    • pokud se metoda neimplementuje, mluvíme o pure virtual metodě, zapisuje se takhle
class Animal {
  public:
    virtual void eat() =0;
}
  • nebo pro změnu chování nějaké metody základní třídy
    • v základní třídě nadefinujeme, jak se má metoda chovat
    • v určité podtřídě chování virtuální metody předefinujeme

polymorfismus

http://www.cplusplus.com/doc/tutorial/polymorphism/

mám obecnou třídu a pak specifické podtřídy. V konstruktoru se inicializuje pro každou specifickou třídu něco jiného. Obecná třída má metodu run. Chci udělat frontu (vector) obecné třídy a při zpracování pak volat metodu run, která zachová podle hodnot nastavených v konstruktoru. Problém: jak to do té fronty dostat?

Když mám objekt obecné třídy, nelze jej přetypovat na různé podtřídy.

http://stackoverflow.com/questions/5313322/c-cast-to-derived-class

lass Animal { /* Some virtual members */ }
class Dog: public Animal {};
class Cat: public Animal {};


Dog     dog;
Cat     cat;
Animal& AnimalRef1 = dog;  // Notice no cast required. (Dogs and cats are animals).
Animal& AnimalRef2 = cat;
Animal* AnimalPtr1 = &dog;
Animal* AnimlaPtr2 = &cat;

Cat&    catRef1 = dynamic_cast<Cat&>(AnimalRef1);  // Throws an exception  AnimalRef1 is a dog
Cat*    catPtr1 = dynamic_cast<Cat*>(AnimalPtr1);  // Returns NULL         AnimalPtr1 is a dog
Cat&    catRef2 = dynamic_cast<Cat&>(AnimalRed2);  // Works
Cat*    catPtr2 = dynamic_cast<Cat*>(AnimalPtr2);  // Works

// This on the other hand makes no sense
// An animal object is not a cat. Therefore it can not be treated like a Cat.
Animal  a;
Cat&    catRef1 = dynamic_cast<Cat&>(a);    // Throws an exception  Its not a CAT
Cat*    catPtr1 = dynamic_cast<Cat*>(&a);   // Returns NULL         Its not a CAT.
Animal   animal = cat;    // This works. But it slices the cat part out and just
                          // assigns the animal part of the object.
Cat      bigCat = animal; // Makes no sense.
                          // An animal is not a cat!!!!!
Dog      bigDog = bigCat; // A cat is not a dog !!!!
std::vector<Animal*>  barnYard;
barnYard.push_back(&dog);
barnYard.push_back(&cat);
barnYard.push_back(&duck);
barnYard.push_back(&chicken);

Dog*  dog = dynamic_cast<Dog*>(barnYard[1]); // Note: return NULL as this was the cat.

SLT kontejnery

  • array - statické pole. Alokuje se při kompilaci.
  • vector - dynamické pole. Automaticky alokuje paměť.
prog_cpp.1463741172.txt.gz · Poslední úprava: (upraveno mimo DokuWiki)

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki