C++: Could Polymorphic Copy Constructors work?

喜夏-厌秋 提交于 2019-12-18 13:34:14

问题


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?


回答1:


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;
}



回答2:


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)




回答3:


Just a small addition to the answer by eduffy: Instead of

class B : public A {
  ...
  A *Clone() { return new B(*this); } 
  ...

};

you can declare it like this:

class B : public A {
  ...
  B *Clone() { return new B(*this); } // note: returning B *
  ...

};

It's still considered a valid overriding of the virtual A::Clone(); and is better if called directly through B *




回答4:


The expression

new A(*b1)

already has a meaning, supposing you had the appropriate overload.

If it was given a different meaning, you'd have to provide another way to get the other meaning. This is kind of pointless given that there is already a way to get the meaning you want:

new B(*b1)

And guess which is clearer to read.




回答5:


Yes. No.

There are a number of ways of implementing cloning (e.g. the more or less standard clone() method, parameterized variations of object factories, with or without configurable dependency injection) without changing the meaning of existing programs, or making it impossible to create instances of base classes when a derived class is known within a compilation unit.

Constructors and destructors are sufficiently complex to understand for beginners as is. Injecting even more complexity into them would be unwise.




回答6:


As pointed out above there are a number of ways of implementing this.

To answer your question if new A( *b1 ) returned an new instance of B then this would not work.

int main()
{
    A* b1 = new B( 1, 2 );
    A a( *b1 ); // What size would 'a' be if it was polymorphicly constructed?
    return 0;
}


来源:https://stackoverflow.com/questions/1021626/c-could-polymorphic-copy-constructors-work

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!