Can we make a class copy constructor virtual in C++? How to use?
No you can't, constructors can't be virtual.
C++03 - 12.1 Constructors
4) A constructor shall not be
virtual
(10.3) orstatic
(9.4). [...]
If you need something like this, you can look up the virtual constructor idiom here.
No you cannot.
Furthermore, the whole concept does not make sense. Virtual functions are functions that are dispatched based on the value of an object (the dynamic type of the object). When a constructor is called, the object does not yet have a value (because it has not yet been constructed). Therefore, no virtual dispatch can possibly occur.
Think about it. What semantics would such a constructor have?
No. C++ being static typed language, it is meaningless to the C++ compiler to create an object polymorphically. The compiler must be aware of the class type to create the object. In other words, what type of object to be created is a compile time decision from C++ compiler perspective. If we make constructor virtual, compiler flags an error.
You cannot because the memory is allocated before the constructor is called based on the size of the new type not the copy operand. And if it did work it would be a special case that inverted polymorphism for a number of language constructs.
But that doesn't mean it can't be done with a little C++ magic. :)
There are couple cases where it is incredibly helpful, Serializing non-POD classes for instance. This example creates a virtual copy constructor that works using placement new.
Warning: This is an example that may help some users with specific problems. Do not do this in general purpose code. It will crash if the memory allocated for the new class is smaller than the derived class. The best (and only) safe way to use this is if you are managing your own class memory and using placement new.
class VirtualBase
{
public:
VirtualBase() {}
virtual ~VirtualBase() {}
VirtualBase(const VirtualBase& copy)
{
copy.VirtualPlacementCopyConstructor(this);
}
virtual void VirtualPlacementCopyConstructor(void*) const {}
};
class Derived :: public VirtualBase
{
public:
...
Derived(const Derived& copy) : ... don't call baseclass and make an infinite loop
{
}
protected:
void VirtualPlacementCopyConstructor(void* place) const
{
new (place) Derived(*this);
}
};
Derived
will suffer from double initialization. This might happen to work with some simple types, but clearly results in undefined behavior. The "constructor" would need to be void VirtualPlacementCopyConstructor(VirtualBase* place) const { auto d = dynamic_cast<Derived*>(place); if (d) { d->~Derived(); new (d) Derived(*this); } }
–
Codding VirtualPlacementCopyConstructor
is invoked way too early, when the type of the copied-into class is not Derived
yet. Thus the destructor won't do the right thing either, and you get undefined behavior aplenty. If you replace dynamic_cast
with static_cast
, things will work for POD types, and that's about it. As soon as you add e.g. a std::string
member, stuff will break (worse yet: it won't always break, so you'll be pulling your hair out). –
Codding The solution being worked on by those close to the standards committee is the value_types
proposal. You will still not directly be able to copy
polymorphic types. However with a wrapper it becomes trivial to copy any polymorphic type.
That is with class Base
and class Derived : public Base
you construct Derived
instances like so, with arg0
and arg1
being arguments to Derived
s constructor.
std::polymorphic<Base> v =
std::polymorphic<Base>(
std::in_place_type_t<Derived>{},
arg0,
arg1
);
and can then simply copy the value around
auto v2 = v;
without any risk of slicing.
https://github.com/jbcoe/value_types
For example, the below code shows the copying of polymorphic types without any extra clone
or deepcopy
virtual members. The requirement is just to construct the object into a polymorphic
wrapper which captures the constructor of the real type.
https://godbolt.org/z/1fbxE7Pxc
#include <https://raw.githubusercontent.com/jbcoe/value_types/main/indirect.h>
#include <https://raw.githubusercontent.com/jbcoe/value_types/main/polymorphic.h>
#include <vector>
#include <utility>
class Base {
public:
Base(){}
virtual int foo() = 0;
virtual ~Base() = default;
};
class Child : public Base {
public:
Child(int _x):x(_x){}
int foo() override { return x;}
int x;
};
class Child2 : public Base {
public:
Child2(int _y):y(_y){}
int foo() override { return y;}
int y;
};
int main()
{
std::vector<xyz::polymorphic<Base>> vec;
vec.push_back(xyz::polymorphic<Base>(Child(189)));
vec.push_back(xyz::polymorphic<Base>(Child(97)));
vec.push_back(xyz::polymorphic<Base>(std::in_place_type_t<Child2>{},66));
assert(vec[0]->foo() == 189);
assert(vec[1]->foo() == 97);
assert(vec[2]->foo() == 66);
auto b = vec;
assert(b[0]->foo() == 189);
assert(b[1]->foo() == 97);
assert(b[2]->foo() == 66);
}
For a slightly simpler implementation than in the official repo one can inspect
https://godbolt.org/z/sT7asfozG
to see how one would go about creating such a system. The central idea is to capture a function pointer with the signature.
template <typename DerivedT>
requires std::convertible_to<DerivedT*,BaseT*>
static std::unique_ptr<BaseT> CopyFunction(BaseT const& v) {
return std::make_unique<DerivedT>(*static_cast<DerivedT const*>(&v));
}
which is just type erasing a function pointer implementing
std::make_unique<DerivedT>(vDerived)
and storing the function pointer in a control block so that even though the wrapper manifests as polymorphic<Base>
internally it holds the function pointer for copying Derived
Yes you can create virtual copy constructor but you can not create virtual constructor.
Reason:
Virtual Constructor:- Not Possible because c++ is static type language and create constructor as a virtual so compiler won't be able to decide what type of object it and leave the whole process for run time because of virtual keyword. The compiler must be aware of the class type to create the object. In other words, what type of object to be created is a compile time decision from C++ compiler perspective. If we make constructor virtual, compiler flags an error.
Virtual Copy constructor:- Yes Possible, consider clip board application. A clip board can hold different type of objects, and copy objects from existing objects, pastes them on application canvas. Again, what type of object to be copied is a runtime decision. Virtual copy constructor fills the gap here.
© 2022 - 2025 — McMap. All rights reserved.