What happens if I cut to an abstract class

First, I know that an assignment operator cannot be defined in a class that has some subclasses. I understand this because we do not want to make Subclass1 = Subclass2it possible.

But suppose that it Classis an abstract class, and Subclassis it ... I know. Then is it possible to do something like this?

Class* p = new Subclass;
Subclass s1;
*p = s1;

Actually, I tried to implement this in my code, but it did not work :) Could you help?

My full code is:

#include <cstdlib>
#include <iostream>
#include <typeinfo>

using namespace std;

class BadIndex{
    int index;
public:
    BadIndex(int i):index(i){}
    int getIndex(){ return index; }
};

template <typename t>
class Wielomian{
public:
    ~Wielomian(){}
    virtual int getDeg() = 0;
    virtual t& operator [](int) = 0;
    virtual bool operator ==(Wielomian<t>&) = 0;
    virtual Wielomian<t>& operator +(Wielomian<t>&) = 0;
    virtual Wielomian<t>& operator +=(Wielomian<t>&) = 0;
};

template <typename t>
class TabWiel: public Wielomian<t>{
    int deg;
    t* plnml;
public:
    TabWiel(t tab[] = {}, int size = 0);
    ~TabWiel();
    TabWiel(const TabWiel<t>&);
    TabWiel<t>& operator =(const TabWiel<t>&);

    template <typename st>
    friend ostream& operator <<(ostream& s, TabWiel<st>& tw);                                             
    int getDeg(){ return deg; }
    t& operator [](int);
    bool operator ==(Wielomian<t>&);
    TabWiel<t>& operator +(Wielomian<t>&);
    TabWiel<t>& operator +=(Wielomian<t>&);
};

template <typename t>
TabWiel<t>& TabWiel<t>::operator =(const TabWiel<t>& tw){
    if (this != &tw){
        delete[] plnml;
        deg = tw.deg;
        plnml = new t[deg + 1];
        for (int i = 0; i < deg + 1; i++)
            plnml[i] = tw.plnml[i];
    }
    return *this;
}

template <typename t>
TabWiel<t>::TabWiel(t tab[], int size){
    deg = size - 1;
    plnml = new t[deg + 1];
    for (int i = 0; i < deg + 1; i++)
        plnml[i] = tab[i];
    if (deg == -1){
        deg = 0;
        plnml[0] = 0;
    }
}

template <typename t>
TabWiel<t>::~TabWiel(){
    delete[] plnml;
}

template <typename t>
TabWiel<t>::TabWiel(const TabWiel<t>& tw){
    deg = tw.deg;
    plnml = new t[deg + 1];
    for (int i = 0; i < deg + 1; i++)
        plnml[i] = tw.plnml[i];
}

template <typename t>
t& TabWiel<t>::operator [](int s){
    if (s >= 0 && s < deg + 1)
        return plnml[s];
    else
        throw BadIndex(s);
}

template <typename t>
bool TabWiel<t>::operator ==(Wielomian<t>& tw){
    try{
        TabWiel<t>& rhs = dynamic_cast<TabWiel<t>&>(tw);
        if (deg == rhs.deg){
            for (int i = 0; i < deg + 1; i++){
                if (plnml[i] != rhs.plnml[i])
                    return false;
            }
            return true;
        }
        return false;
    }
    catch (const bad_cast& e){
        cerr << "An exception" << e.what() << " thrown." << endl;
    }
}

template <typename t>
ostream& operator <<(ostream& s, TabWiel<t>& tw){
    for (int i = 0; i < tw.deg + 1; i++){
        if (i != tw.deg)
            s << tw.plnml[i] << "x^" << i << "+";
        else
            s << tw.plnml[i] << "x^" << i << endl;
    }
    return s;
}

template <typename t>
TabWiel<t>& TabWiel<t>::operator +(Wielomian<t>& tw){
    try{
        TabWiel<t>& rhs = dynamic_cast<TabWiel<t>&>(tw);
        if (rhs.deg <= deg){
            for (int i = 0; i < rhs.deg + 1; i++)
                plnml[i] = plnml[i] + rhs.plnml[i];
            return *this;
        }
        else{
            t* tmp = new t[deg + 1];
            for (int i = 0; i < deg + 1; i++)
                tmp[i] = plnml[i];
            int tmp_deg = deg;
            delete[] plnml;
            deg = rhs.deg;
            plnml = new t[deg + 1];
            for (int i = 0; i < deg + 1; i++){
                if(i < tmp_deg + 1)
                    plnml[i] = tmp[i] + rhs.plnml[i];
                else
                    plnml[i] = rhs.plnml[i];
            }
            return *this;
        }
    }
    catch (const bad_cast& e){
        cerr << "An exception" << e.what() << " thrown." << endl;
    }
}

template <typename t>
TabWiel<t>& TabWiel<t>::operator +=(Wielomian<t>& tw){
    try{
        TabWiel<t>& rhs = dynamic_cast<TabWiel<t>&>(tw);
        TabWiel<t>* nowy = new TabWiel<t>;
        TabWiel<t> copy;
        copy = *this;
        *nowy = copy + rhs;
        return *nowy;
    }
    catch (const bad_cast& e){
        cerr << "An exception" << e.what() << " thrown." << endl;
    }
}

, *p . - , , , "Wielomian", main ( ).

+4
1

.

, - slicing: Subclass, , Class. , .

, ellaborate gha.st :

struct Class { int a; virtual void hugo() = 0; };
struct Subclass : Class { int b; void hugo() override { cout<<"sub"<<a<<b<<endl; } };
int main() {
    Class* p = new Subclass;
    static_cast<Subclass*>(p)->a = 2; 
    static_cast<Subclass*>(p)->b = 3; 
    Subclass s1;
    s1.a = 4; s1.b=5;
    *p = s1;  // slicing !!  
    p->hugo();
    return 0;
}  

? , b , *p Subclass!

*p - Subclass, . clone() ( ) , .
operator=() Class, clone(). , , operator= Class, .

:

struct Class {
    int a; 
    virtual void hugo() = 0; 
    virtual bool clone(Class*t) = 0; 
    Class& operator=(Class& o) {
        if (!o.clone(this)) {  // try to clone on subclass on a target of same subclass
            // here,the source and target might differ. Only common members can be copied
            a = o.a; 
        }
        return *this; 
    }
};
struct Subclass : Class {
    int a,b; 
    void hugo() override { cout<<"sub"<<a<<b<<endl; } 
    bool clone(Class*t) { 
        cout<<"Clone "; 
        if (dynamic_cast<Subclass*>(t)) {  // if source and target of same subclass
             //*dynamic_cast<Subclass*>(t) = *this;  // this doesn't work cause default operator will try to copy the Class base, causing recursion
             dynamic_cast<Subclass*>(t)->a = a;   // copy members
             dynamic_cast<Subclass*>(t)->b = b;
             return true; 
        }
        else return false; // or tell that class of source and target are different. 
    } 
};

main() , .

. , .

+2

All Articles