2

Let's say I have a class A and B where B derives from A. And later I have a pointer A* which can point to an object class A or object class B. Now I'd like to copy this object under pointer without knowledge which object is pointed to by this pointer so if there is an A object then I'd like to copy an A object but if it's B then I'd like to copy B. I'd like to omit RTTI and dynamic casting. Do you have an idea how to do it? Or must I implement something like virtual cloning function and call it explicitly?

2
  • What have you tried... And what is going wrong? We work with code, we don't generate it. Commented Aug 21, 2013 at 17:02
  • 5
    " Or i must implement something like virtual cloning function and call it explicit?" Yes, that. (You can search for "clone" and "virtual copy constructor".) Commented Aug 21, 2013 at 17:03

2 Answers 2

4

The cloning virtual function is the most typical approach for this, for example as

class Base {
    public: virtual Base* clone() { return new Base(*this); }
};

class Derived : public Base {
    public: virtual Base* clone() { return new Derived(*this); }
};

Sometimes however, when you have a pointer to Derived and you clone it, you suddenly have a pointer to Base while you know that it is derived. A down-cast is then needed, if you want to access Derived-specific members.

According to C++98-standard you can actually change the return type to the derived type, e.g.

class Base {
    public: virtual Base* clone() { return new Base(*this); }
};

class Derived : Base {
    public: virtual Derived* clone() { return new Derived(*this); } //will overload Base::clone
};
Sign up to request clarification or add additional context in comments.

3 Comments

Not only "some" compilers, every Standard-compliant compiler. It's called "covariant return type" and has been incorporated in the C++98 Standard a long time ago. By the way you're missing a public, it should be class Derived : public Base (otherwise "the outside" can't convert a Derived* to Base*)
Oh, that information about covariant return type can be very useful, thanks!
@gx_ fixed as per your comment
0

In the simple case of memberwise copy it seems strightforward:

#include<iostream>
using namespace std;

class A{
public:
    ~A(){}
    A() : _x('A') {}
    void foo() { cout << _x << endl; }   
protected:
    char _x;    
};

class B : public A{
public:
    ~B(){}
    B() { _x = 'B';}
};

int main()
{
    A* a = new A();
    A* b = new B();

    A* c(a);
    c->foo();  //A

    A* d(b);
    d->foo();   //B

    delete a,b;
}

3 Comments

You're just copying pointers. The OP wanted to copy objects through pointers (and has already been answered). Besides, delete a,b; is horribly wrong, it's basically like delete a; then b; alone (statement with no effect), so you delete the A but not the B (warning: right operand of comma operator has no effect + live example). And even if you fix that, you'll be deleting a B through a pointer-to-A and A's destructor is not virtual, so it will call the wrong destructor. ("The amazing C++ genius", says your signature... you have a sense of humor.)
@gx_: Thanx, you have thought me alot.
My answer is wrong but I will not delete it as I found gx_ comment useful

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.