Ich möchte eine Typ -Lodure -Techniken erhalten und gleichzeitig diese teilen, von denen ich weiß. Meine Hoffnung ist es, eine verrückte Technik zu finden, über die jemand in seiner dunkelsten Stunde dachte.

Der erste und offensichtlichste und am häufigsten verfolgte Ansatz, den ich kenne, sind virtuelle Funktionen. Verstecken Sie einfach die Implementierung Ihrer Klasse in einer interface -basierten Klassenhierarchie. Viele Boost -Bibliotheken tun dies, zum Beispiel Boost.any, um Ihren Typ zu verbergen, und Boost.shared_Ptr verbergen dies (DE) Allocation -Mechaniker. < /p>
Dann gibt es die Option mit Funktionszeiger auf Vorlagenfunktionen, während das tatsächliche Objekt in einem Void*< /code> Zeiger wie Boost.function hält, um den realen Typ des Functors zu verbergen. Beispielimplementierungen finden Sie am Ende der Frage. Bitte geben Sie ihnen nach Möglichkeit einen Beispielcode, Anwendungsfälle, Ihre Erfahrung mit ihnen und möglicherweise Links zum weiteren Lesen an. Funktionen oder void*< /code> Fiddeln, ist derjenige, der hier verwendet wird, mit Relevanz für meine Frage, wie genau dies funktioniert.
Code: Select all
#include
#include
// NOTE: The class name indicates the underlying type erasure technique
// this behaves like the Boost.Any type w.r.t. implementation details
class Any_Virtual{
struct holder_base{
virtual ~holder_base(){}
virtual holder_base* clone() const = 0;
};
template
struct holder : holder_base{
holder()
: held_()
{}
holder(T const& t)
: held_(t)
{}
virtual ~holder(){
}
virtual holder_base* clone() const {
return new holder(*this);
}
T held_;
};
public:
Any_Virtual()
: storage_(0)
{}
Any_Virtual(Any_Virtual const& other)
: storage_(other.storage_->clone())
{}
template
Any_Virtual(T const& t)
: storage_(new holder(t))
{}
~Any_Virtual(){
Clear();
}
Any_Virtual& operator=(Any_Virtual const& other){
Clear();
storage_ = other.storage_->clone();
return *this;
}
template
Any_Virtual& operator=(T const& t){
Clear();
storage_ = new holder(t);
return *this;
}
void Clear(){
if(storage_)
delete storage_;
}
template
T& As(){
return static_cast(storage_)->held_;
}
private:
holder_base* storage_;
};
// the following demonstrates the use of void pointers
// and function pointers to templated operate functions
// to safely hide the type
enum Operation{
CopyTag,
DeleteTag
};
template
void Operate(void*const& in, void*& out, Operation op){
switch(op){
case CopyTag:
out = new T(*static_cast(in));
return;
case DeleteTag:
delete static_cast(out);
}
}
class Any_VoidPtr{
public:
Any_VoidPtr()
: object_(0)
, operate_(0)
{}
Any_VoidPtr(Any_VoidPtr const& other)
: object_(0)
, operate_(other.operate_)
{
if(other.object_)
operate_(other.object_, object_, CopyTag);
}
template
Any_VoidPtr(T const& t)
: object_(new T(t))
, operate_(&Operate)
{}
~Any_VoidPtr(){
Clear();
}
Any_VoidPtr& operator=(Any_VoidPtr const& other){
Clear();
operate_ = other.operate_;
operate_(other.object_, object_, CopyTag);
return *this;
}
template
Any_VoidPtr& operator=(T const& t){
Clear();
object_ = new T(t);
operate_ = &Operate;
return *this;
}
void Clear(){
if(object_)
operate_(0,object_,DeleteTag);
object_ = 0;
}
template
T& As(){
return *static_cast(object_);
}
private:
typedef void (*OperateFunc)(void*const&,void*&,Operation);
void* object_;
OperateFunc operate_;
};
int main(){
Any_Virtual a = 6;
std::cout