Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: Could Polymorphic Copy Constructors work?

Consider:

class A
{
public:
    A( int val ) : m_ValA( val ) {}
    A( const A& rhs ) {}
    int m_ValA;
};

class B : public A
{
public:
    B( int val4A, int val4B ) : A( val4A ), m_ValB( val4B ) {}
    B( const B& rhs ) : A( rhs ), m_ValB( rhs.m_ValB ) {}
    int m_ValB;
};

int main()
{
    A* b1 = new B( 1, 2 );
    A* b2 = new A( *b1 ); // ERROR...but what if it could work?
    return 0;
}

Would C++ be broken if "new A( b1 )" was able to resolve to creating a new B copy and returning an A?

Would this even be useful?

like image 398
0xC0DEFACE Avatar asked Jun 20 '09 13:06

0xC0DEFACE


2 Answers

Do you need this functionality, or is this just a thought experiment?

If you need to do this, the common idiom is to have a Clone method:

class A
{
public:
    A( int val ) : m_ValA( val ) {}
    A( const A& rhs ) {}
    virtual A *Clone () = 0;
    int m_ValA;
};

class B : public A
{
public:
    B( int val4A, int val4B ) : A( val4A ), m_ValB( val4B ) {}
    B( const B& rhs ) : A( rhs ), m_ValB( rhs.m_ValB ) {}
    A *Clone() { return new B(*this); }
    int m_ValB;
};

int main()
{
    A* b1 = new B( 1, 2 );
    A* b2 = b1->Clone();
    return 0;
}
like image 153
eduffy Avatar answered Sep 19 '22 08:09

eduffy


What you're really looking for is called a virtual copy constructor, and what eduffy posted is the standard way of doing it.

There are also clever ways of doing it with templates. (disclaimer: self-promotion)

like image 41
Tyler McHenry Avatar answered Sep 20 '22 08:09

Tyler McHenry