Date: Tue, 23 Aug 2022 12:28:33 +0100
At first I was going to suggest that classes such as "unique_ptr",
"shared_ptr" and "weak_ptr" should inherit from a common interface
which has a virtual destructor, something like:
class ISmartPtr {
public:
virtual ~ISmartPtr(void);
};
class unique_ptr : public ISmartPtr { . . . };
class shared_ptr : public ISmartPtr { . . . };
class weak_ptr : public ISmartPtr { . . . };
So this would mean that we could have a container that automatically
destroys any kind of smart pointer as follows:
vector<ISmartPtr> my_vector;
But then I thought it would be useful if *every* class inherited from
a class with a virtual destructor. As if doing this:
struct MyClass { int a; }
would be the same as:
struct BaseClassWithVirtualDestructor { virtual
~BaseClassWithVirtualDestructor(){} };
struct MyClass : public BaseClassWithVirtualDestructor {
int a;
};
But of course that would mean that all simple POD's would have the
overhead of a pointer to a v-table (and also the address of the first
member would not be equal to the address of the object -- on most
architectures).
But then I thought of another idea, how about we have a new type
called "dvoid", and a new cast called 'virtual_destructor_cast':
Some_POD_Class a;
Some_Complicated_Class_With_Virtual_Destructor b;
dvoid *p = virtual_destructor_cast<dvoid*>(&a); // This returns a nullptr
dvoid *p = virtual_destructor_cast<dvoid*>(&b); // This returns a
valid pointer
And then you can use this pointer as follows:
p->~dvoid();
or perhaps an alternative syntax would be:
std::destroy(p);
So then you could have a container of pointers to anything that can be
destroyed:
std::vector<dvoid*> objects;
In order to implement the 'dvoid*' type on a system where a pointer is
8 bytes, the 'dvoid' type could be 16 bytes, as internally it would be
two pointers:
(1) The pointer to the object
(2) The pointer to the destructor of the object (possibly obtained
from the v-table)
"shared_ptr" and "weak_ptr" should inherit from a common interface
which has a virtual destructor, something like:
class ISmartPtr {
public:
virtual ~ISmartPtr(void);
};
class unique_ptr : public ISmartPtr { . . . };
class shared_ptr : public ISmartPtr { . . . };
class weak_ptr : public ISmartPtr { . . . };
So this would mean that we could have a container that automatically
destroys any kind of smart pointer as follows:
vector<ISmartPtr> my_vector;
But then I thought it would be useful if *every* class inherited from
a class with a virtual destructor. As if doing this:
struct MyClass { int a; }
would be the same as:
struct BaseClassWithVirtualDestructor { virtual
~BaseClassWithVirtualDestructor(){} };
struct MyClass : public BaseClassWithVirtualDestructor {
int a;
};
But of course that would mean that all simple POD's would have the
overhead of a pointer to a v-table (and also the address of the first
member would not be equal to the address of the object -- on most
architectures).
But then I thought of another idea, how about we have a new type
called "dvoid", and a new cast called 'virtual_destructor_cast':
Some_POD_Class a;
Some_Complicated_Class_With_Virtual_Destructor b;
dvoid *p = virtual_destructor_cast<dvoid*>(&a); // This returns a nullptr
dvoid *p = virtual_destructor_cast<dvoid*>(&b); // This returns a
valid pointer
And then you can use this pointer as follows:
p->~dvoid();
or perhaps an alternative syntax would be:
std::destroy(p);
So then you could have a container of pointers to anything that can be
destroyed:
std::vector<dvoid*> objects;
In order to implement the 'dvoid*' type on a system where a pointer is
8 bytes, the 'dvoid' type could be 16 bytes, as internally it would be
two pointers:
(1) The pointer to the object
(2) The pointer to the destructor of the object (possibly obtained
from the v-table)
Received on 2022-08-23 11:28:44