ভাগ করা লাইব্রেরিগুলির সাথে একটি সত্যিকারের সমস্যা রয়েছে যে পিম্পল আইডিয়ম সুস্পষ্টরূপে পরিষ্কার করে দেয় যে খাঁটি ভার্চুয়ালগুলি পারবেন না: আপনি ক্লাসের ব্যবহারকারীদের তাদের কোডটি পুনরায় সংকলন করতে বাধ্য না করে কোনও শ্রেণীর ডেটা সদস্যকে নিরাপদে সংশোধন / অপসারণ করতে পারবেন না। এটি কিছু পরিস্থিতিতে গ্রহণযোগ্য হতে পারে তবে সিস্টেম লাইব্রেরির ক্ষেত্রে যেমন নয় not
সমস্যাটি বিস্তারিতভাবে ব্যাখ্যা করতে, আপনার ভাগ করা লাইব্রেরি / শিরোনামে নিম্নলিখিত কোডটি বিবেচনা করুন:
// header
struct A
{
public:
A();
// more public interface, some of which uses the int below
private:
int a;
};
// library
A::A()
: a(0)
{}
ভাগ গ্রন্থাগার যে পূর্ণসংখ্যা এর ঠিকানা হিসাব মধ্যে কম্পাইলার নিঃসরণ করে কোড (সম্ভবত এই ক্ষেত্রে শূন্য কারণ এটি শুধুমাত্র সদস্য) একটি নির্দিষ্ট অফসেট হতে সক্রিয়া হতো তার বস্তুর এটা হতে জানে পয়েন্টার থেকে this
।
কোডটির ব্যবহারকারীর দিকে, একটি new A
প্রথমে sizeof(A)
মেমরির বাইটগুলি বরাদ্দ করবে , তারপরে সেই মেমোরিটির জন্য একটি পয়েন্টারকে A::A()
কনস্ট্রাক্টর হিসাবে হস্তান্তর করবে this
।
যদি আপনার লাইব্রেরির পরে কোনও সংশোধন করে আপনি পূর্ণসংখ্যাটি ফেলে ফেলা, এটি আরও বড়, আরও ছোট বা সদস্য যুক্ত করার সিদ্ধান্ত নেন তবে মেমরির ব্যবহারকারীর কোড বরাদ্দ করার পরিমাণ এবং কনস্ট্রাক্টর কোড প্রত্যাশিত অফসেটগুলির মধ্যে একটি মিল নেই। সম্ভাব্য ফলাফলটি ক্র্যাশ, যদি আপনি ভাগ্যবান হন - যদি আপনি কম ভাগ্যবান হন তবে আপনার সফ্টওয়্যারটি অদ্ভুত আচরণ করে।
পিম্পলিংয়ের মাধ্যমে, আপনি ভাগ করে নেওয়া লাইব্রেরিতে মেমরির বরাদ্দ এবং কনস্ট্রাক্টর কল হওয়ায় আপনি নিরাপদভাবে অভ্যন্তরীণ শ্রেণিতে ডেটা সদস্যদের যুক্ত করতে বা মুছতে পারেন:
// header
struct A
{
public:
A();
// more public interface, all of which delegates to the impl
private:
void * impl;
};
// library
A::A()
: impl(new A_impl())
{}
আপনাকে এখনই যা করতে হবে তা হ'ল আপনার সার্বজনীন ইন্টারফেসটিকে বাস্তবায়ন অবজেক্টের পয়েন্টার ব্যতীত ডেটা সদস্যদের মুক্ত রাখতে হবে এবং আপনি এই শ্রেণীর ত্রুটি থেকে নিরাপদ।
সম্পাদনা: আমার সম্ভবত যুক্ত করা উচিত যে আমি এখানে নির্মাণকারীর কথা বলার একমাত্র কারণ হ'ল আমি আরও কোড সরবরাহ করতে চাইনি - একই যুক্তি ডেটা সদস্যদের অ্যাক্সেস করে এমন সমস্ত ফাংশনে প্রযোজ্য।