Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Tworzenie kopi siebie samego(obiektu) z wykorzystaniem wirtualnej funkcji

Ostatnio zmodyfikowano 2014-04-07 10:11
Autor Wiadomość
xaoc
Temat założony przez niniejszego użytkownika
Tworzenie kopi siebie samego(obiektu) z wykorzystaniem wirtualnej funkcji
» 2014-04-07 00:23:20
Więc

C/C++
#include <iostream>
using namespace std;

class Base {
public:
    virtual Base * clone() { cout << "Base"; return this; }
};

class Derived
    : public Base
{
public:
    virtual Derived * clone() { cout << "Derived"; return /*(Derived*)*/ this; }
};

int main() {
    Derived d;
    Base * b = & d;
    Derived * dd = b->clone(); // Dlaczego to coś nie chce się przypisać i jak zrobić żeby przypisało
}

Przedostatnia linijka. Z góry dziękuję za wyjaśnienie.
P-107814
Monika90
» 2014-04-07 07:34:26
Dlaczego to coś nie chce się przypisać i jak zrobić żeby przypisało
Statyczna kontrola typów. b->clone() zwraca Base*, a nie każdy wskaźnik do Base wskazuje na Derived, niejawna konwersja Base* do Derived* byłaby niebezpieczna. Chcesz mieć dynamiczną kontrolę typów - użyj dynamic_cast
C/C++
if( auto dd = dynamic_cast < Derived *>( b->clone() ) )
     cout << "tym razem się udało";
else
     cout << "masz pecha";

P-107818
xaoc
Temat założony przez niniejszego użytkownika
» 2014-04-07 10:11:41
Nie do końca o to mi chodziło.
C/C++
//: C15:VariantReturn.cpp
// Kod zrodlowy pochodzacy z ksiazki
// "Thinking in C++. Edycja polska"
// (c) Bruce Eckel 2000
// Informacje o prawie autorskim znajduja sie w pliku Copyright.txt
// Zwracanie wskaznika lub referencji
// do typu pochodnego w czasie zaslaniania
#include <iostream>
#include <string>
using namespace std;

class PetFood {
public:
    virtual string foodType() const = 0;
};

class Pet {
public:
    virtual string type() const = 0;
    virtual PetFood * eats() = 0;
};

class Bird
    : public Pet
{
public:
    string type() const { return "Ptak"; }
    class BirdFood
        : public PetFood
    {
    public:
        string foodType() const {
            return "nasiona";
        }
    };
    // Rzutowanie w gore do typu podstawowego:
    PetFood * eats() { return & bf; }
private:
    BirdFood bf;
};

class Cat
    : public Pet
{
public:
    string type() const { return "Kot"; }
    class CatFood
        : public PetFood
    {
    public:
        string foodType() const { return "ptaki"; }
    };
    // Zwracany jest dokladny typ:
    CatFood * eats() { return & cf; }
private:
    CatFood cf;
};

int main() {
    Bird b;
    Cat c;
    Pet * p[] = { & b, & c, };
    for( int i = 0; i < sizeof p / sizeof * p; i++ )
    cout << p[ i ]->type() << " je "
         << p[ i ]->eats()->foodType() << endl;
    // Funkcja moze zwrocic dokladny typ:                                   !!!
    Cat::CatFood * cf = c.eats();
    Bird::BirdFood * bf;
    // Funkcja nie moze zwrocic dokladnego typu:
    //!  bf = b.eats();
    // Trzeba rzutowac w dol:
    bf = dynamic_cast < Bird::BirdFood *>( b.eats() );
} ///:~

Tutaj jakoś może zamienić z klasy podstawowej, na swoją pochodną więc nie rozumiem gdzie robię błąd u siebie. Poza tym że powinno być
C/C++
new Derived( * this ) // Ma to być kopia

"Jeśli funkcja zwraca wsk lub referencje do obiektu klasy podstawowej, to przedefiniowana wersja funkcji może zwrócić wskaźnik lub referencję jej klasy pochodnej"

EDIT
Ok. Widzę c jest klasy Cat.
P-107821
« 1 »
  Strona 1 z 1