(টাইপ ইরেজিওর, আমি একটি বর্গ, কিছুটা মত সংক্রান্ত কিছু বা টাইপ সমস্ত তথ্য গোপন অর্থ Boost.Any ।)
আমি টাইপ ইরেজিওর কৌশল হোল্ড পেতে চান, যখন সেই, যা আমি জানি ভাগ করুন। আমার আশা এমন কিছু পাগল কৌশলটি সন্ধান করতে চাই যা তার সবচেয়ে অন্ধকার সময়ে কেউ ভেবেছিল। :)
প্রথম এবং সর্বাধিক সুস্পষ্ট এবং সাধারণভাবে গ্রহণ করা পদ্ধতি, যা আমি জানি, হ'ল ভার্চুয়াল ফাংশন। একটি ইন্টারফেস ভিত্তিক শ্রেণীর শ্রেণিবিন্যাসের মধ্যে কেবল আপনার শ্রেণির প্রয়োগটি আড়াল করুন। অনেক বুস্ট লাইব্রেরি এটি করেন, উদাহরণস্বরূপ Boost.Any এই আপনার টাইপ লুকাতে করে এবং Boost.Shared_ptr এই (ডি) বরাদ্দ মিস্ত্রি লুকাতে না।
তারপরে ফাংশন পয়েন্টারগুলির সাথে টেম্পলেটড ফাংশনগুলির বিকল্প রয়েছে, যখন void*
পয়েন্টারটিতে আসল অবজেক্টটি ধরে রাখার মতো বুস্ট un ফাংশন ফান্টারের আসল ধরণের আড়াল করতে পারে। প্রশ্নের শেষে উদাহরণ প্রয়োগগুলি পাওয়া যাবে।
সুতরাং, আমার আসল প্রশ্নটির জন্য:
অন্য কোন ধরণের ক্ষয় কৌশল আপনি কী জানেন? যদি তাদের সম্ভব হয় তবে একটি উদাহরণ কোড সহ কেসগুলি ব্যবহার করুন, তাদের সাথে আপনার অভিজ্ঞতা এবং আরও পড়ার জন্য লিঙ্কগুলি সরবরাহ করুন links
সম্পাদনা
(যেহেতু আমি নিশ্চিত ছিলাম না যে এটিকে উত্তর হিসাবে যুক্ত করা, বা কেবলমাত্র প্রশ্নটি সম্পাদনা করা, আমি কেবল নিরাপদটি করব do) ভার্চুয়াল ফাংশন বা ফিডিং ছাড়া
প্রকৃত ধরণের কোনও কিছু আড়াল করার জন্য আরেকটি দুর্দান্ত কৌশল void*
হ'ল একজন GMan এখানে নিযুক্ত আছেন , আমার প্রশ্নের সাথে প্রাসঙ্গিকতার সাথে এটি ঠিক কীভাবে কাজ করে তা।
উদাহরণ কোড:
#include <iostream>
#include <string>
// 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<class T>
struct holder : holder_base{
holder()
: held_()
{}
holder(T const& t)
: held_(t)
{}
virtual ~holder(){
}
virtual holder_base* clone() const {
return new holder<T>(*this);
}
T held_;
};
public:
Any_Virtual()
: storage_(0)
{}
Any_Virtual(Any_Virtual const& other)
: storage_(other.storage_->clone())
{}
template<class T>
Any_Virtual(T const& t)
: storage_(new holder<T>(t))
{}
~Any_Virtual(){
Clear();
}
Any_Virtual& operator=(Any_Virtual const& other){
Clear();
storage_ = other.storage_->clone();
return *this;
}
template<class T>
Any_Virtual& operator=(T const& t){
Clear();
storage_ = new holder<T>(t);
return *this;
}
void Clear(){
if(storage_)
delete storage_;
}
template<class T>
T& As(){
return static_cast<holder<T>*>(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<class T>
void Operate(void*const& in, void*& out, Operation op){
switch(op){
case CopyTag:
out = new T(*static_cast<T*>(in));
return;
case DeleteTag:
delete static_cast<T*>(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<class T>
Any_VoidPtr(T const& t)
: object_(new T(t))
, operate_(&Operate<T>)
{}
~Any_VoidPtr(){
Clear();
}
Any_VoidPtr& operator=(Any_VoidPtr const& other){
Clear();
operate_ = other.operate_;
operate_(other.object_, object_, CopyTag);
return *this;
}
template<class T>
Any_VoidPtr& operator=(T const& t){
Clear();
object_ = new T(t);
operate_ = &Operate<T>;
return *this;
}
void Clear(){
if(object_)
operate_(0,object_,DeleteTag);
object_ = 0;
}
template<class T>
T& As(){
return *static_cast<T*>(object_);
}
private:
typedef void (*OperateFunc)(void*const&,void*&,Operation);
void* object_;
OperateFunc operate_;
};
int main(){
Any_Virtual a = 6;
std::cout << a.As<int>() << std::endl;
a = std::string("oh hi!");
std::cout << a.As<std::string>() << std::endl;
Any_Virtual av2 = a;
Any_VoidPtr a2 = 42;
std::cout << a2.As<int>() << std::endl;
Any_VoidPtr a3 = a.As<std::string>();
a2 = a3;
a2.As<std::string>() += " - again!";
std::cout << "a2: " << a2.As<std::string>() << std::endl;
std::cout << "a3: " << a3.As<std::string>() << std::endl;
a3 = a;
a3.As<Any_Virtual>().As<std::string>() += " - and yet again!!";
std::cout << "a: " << a.As<std::string>() << std::endl;
std::cout << "a3->a: " << a3.As<Any_Virtual>().As<std::string>() << std::endl;
std::cin.get();
}
shared_ptr
এটি প্রতিফলিত করে না, এটি সর্বদা একই হবে, shared_ptr<int>
উদাহরণস্বরূপ, মানক ধারক থেকে ভিন্ন।
As
(গুলি) ফাংশনটি সেভাবে কার্যকর করা হবে না। যেমনটি আমি বলেছি, কোনওভাবেই নিরাপদ ব্যবহারের উপায় নেই! :)
function
, shared_ptr
, any
, ইত্যাদি? তারা সকলেই মিষ্টি মিষ্টি ব্যবহারকারীর সুবিধার জন্য মুছে ফেলা ধরণের কাজ করে।