littlerunaway
littlerunaway

Reputation: 453

issue with abstract classes and inheritence

suppose I have those 2 classes:

class num{
public:
    int a;
    num(){};
    num(int x):a(x){};
    num(const num& n):a(n.a){}
    virtual bool operator==(const num& n)const = 0;
    virtual ~num(){};
};

class tmp: public num{
public:
    tmp(){};
    tmp(int x):num(x){};
    tmp(const num& n): num(n){}
    tmp(const tmp& t): num(t.a){}
    virtual bool operator==(const num& n)const{
        return tmp(n).a == a;
    }
    virtual ~tmp(){};
};

and something like this in main:

int main() {
    num* x = &get(...);

    return 0;
}

get return a reference of type tmp (in this case. in general it returns reference to a type that inherits from num) what I want to do is create another num* y that will point to a copy of *x so that if I change *y I won't change *x. and I can't quite figure out how to do this since num is abstract so I can't create an object of this type to make a copy.

ok and another question. if I overload << operator:

    std::ostream& operator<<(std::ostream& os, const tmp& t){
        return os<<t.a<<endl;
    }

and then try to do this:

cout<<*x<<endl;

I get an error no match for 'operator<<' why is that?

Upvotes: 0

Views: 49

Answers (2)

Mike Seymour
Mike Seymour

Reputation: 254431

You'll need a virtual function to clone an object based on its dynamic type. It will have to return a (preferably smart) pointer to a newly allocated object of the correct type. For example:

class num {
public:
    virtual std::unique_ptr<num> clone() const = 0;
    // other members...
};

class my_num : public num {
public:
    virtual std::unique_ptr<num> clone() const {
        return std::make_unique<my_num>(*this);
    }
    // other members...
};

int main() {
    num* x = &get(...);
    auto y = x->clone();
}

Upvotes: 1

Quentin
Quentin

Reputation: 63114

You're looking for the prototype pattern, also often called clone pattern.

It's basically a pure virtual method

virtual std::unique_ptr<num> clone() const = 0;

... that you declare in num, to be overriden by each derived class. You then just call x->clone(); to get a brand new object of the correct type.

Upvotes: 1

Related Questions