এই প্রায়শই জিজ্ঞাসিত প্রশ্নাগুলি সমষ্টি এবং পিওডি সম্পর্কিত এবং নিম্নলিখিত উপাদানগুলি কভার করে:
- সমষ্টি কি কি ?
- পিওডি কি? (সম্য পুরাতন ডেটা) ?
- তারা কিভাবে সম্পর্কিত?
- তারা কীভাবে এবং কেন বিশেষ?
- সি ++ 11 এর জন্য কী পরিবর্তন হয়?
এই প্রায়শই জিজ্ঞাসিত প্রশ্নাগুলি সমষ্টি এবং পিওডি সম্পর্কিত এবং নিম্নলিখিত উপাদানগুলি কভার করে:
উত্তর:
এই নিবন্ধটি বরং দীর্ঘ। যদি আপনি উভয় সমষ্টি এবং পিওডি (সমান পুরাতন ডেটা) সম্পর্কে জানতে চান তবে সময় নিন এবং এটি পড়ুন। আপনি যদি কেবল সমষ্টিগুলিতে আগ্রহী হন তবে কেবল প্রথম অংশটি পড়ুন। আপনি শুধুমাত্র pods আগ্রহী তারপর আপনি প্রথম সংজ্ঞা, প্রভাব, এবং দলা উদাহরণ পড়তে হবে এবং তারপর আপনি পারে pods ঝাঁপ কিন্তু আমি এখনও তার সম্পূর্ণতা প্রথম অংশ পড়া সুপারিশ করবে। পিওডি সংজ্ঞায়নের জন্য সমষ্টিগুলির ধারণাটি প্রয়োজনীয় essential যদি আপনি কোনও ত্রুটি দেখতে পান (ব্যাকরণ, স্টাইলিস্টিকস, ফর্ম্যাটিং, সিনট্যাক্স ইত্যাদি সহ গৌণও) দয়া করে একটি মন্তব্য করুন, আমি সম্পাদনা করব।
এই উত্তরটি C ++ 03 এ প্রযোজ্য। অন্যান্য সি ++ মানের জন্য দেখুন:
সি ++ স্ট্যান্ডার্ড ( সি ++ 03 8.5.1 §1 ) থেকে আনুষ্ঠানিক সংজ্ঞা :
সমষ্টিগত হ'ল একটি অ্যারে বা একটি শ্রেণি (ধারা 9) যার সাথে ব্যবহারকারী-ঘোষিত কনস্ট্রাক্টর (12.1) নেই, কোনও ব্যক্তিগত বা সুরক্ষিত অ-স্থিতিশীল ডেটা সদস্য নয় (ধারা 11), কোনও বেস ক্লাস (ধারা 10) এবং কোনও ভার্চুয়াল ফাংশন (10.3) )।
সুতরাং, ঠিক আছে, আসুন এই সংজ্ঞাটি বিশ্লেষণ করুন। প্রথমত, যে কোনও অ্যারে একটি সমষ্টি। একটি ক্লাসও সামগ্রিক হতে পারে যদি… অপেক্ষা করুন! স্ট্রাইক বা ইউনিয়ন সম্পর্কে কিছুই বলা হয় না, তারা কি সমষ্টি হতে পারে না? হ্যা তারা পারে. সি ++ এ শব্দটি class
সমস্ত শ্রেণি, স্ট্রাক্ট এবং ইউনিয়নগুলিকে বোঝায়। সুতরাং, একটি শ্রেণি (বা কাঠামো, বা ইউনিয়ন) একটি সামগ্রিক যদি কেবল এবং যদি এটি উপরের সংজ্ঞাগুলি থেকে মানদণ্ডকে সন্তুষ্ট করে তবেই। এই মানদণ্ডগুলি কী বোঝায়?
এর অর্থ এই নয় যে একটি সামগ্রিক শ্রেণীর কনস্ট্রাক্টর থাকতে পারে না, আসলে এটির মধ্যে পূর্বনির্ধারিত কনস্ট্রাক্টর এবং / অথবা একটি অনুলিপি নির্ধারক থাকতে পারে যতক্ষণ না তারা সংকলক দ্বারা সুস্পষ্টভাবে ঘোষণা করা হয়, এবং ব্যবহারকারী দ্বারা স্পষ্টত না হয়
কোনও ব্যক্তিগত বা সুরক্ষিত অ-স্থিতিশীল ডেটা সদস্য নয় । আপনার পছন্দ মতো এবং সামগ্রিক শ্রেণীর নিয়ম লঙ্ঘন না করার মতো অনেকগুলি ব্যক্তিগত এবং সুরক্ষিত সদস্য ফাংশন (তবে নির্মাণকারী নয়) পাশাপাশি অনেকগুলি ব্যক্তিগত বা সুরক্ষিত স্ট্যাটিক ডেটা সদস্য এবং সদস্য ফাংশন থাকতে পারে have
একটি সামগ্রিক শ্রেণিতে একটি ব্যবহারকারী-ঘোষিত / ব্যবহারকারীর সংজ্ঞায়িত অনুলিপি-অনাইনমেন্ট অপারেটর এবং / অথবা ডেস্ট্রাক্টর থাকতে পারে
একটি অ্যারে হ'ল একটি সমষ্টিগত এমনকি এটি অ-সমষ্টিগত শ্রেণির ধরণের অ্যারে হলেও।
এখন কয়েকটি উদাহরণ তাকান:
class NotAggregate1
{
virtual void f() {} //remember? no virtual functions
};
class NotAggregate2
{
int x; //x is private by default and non-static
};
class NotAggregate3
{
public:
NotAggregate3(int) {} //oops, user-defined constructor
};
class Aggregate1
{
public:
NotAggregate1 member1; //ok, public member
Aggregate1& operator=(Aggregate1 const & rhs) {/* */} //ok, copy-assignment
private:
void f() {} // ok, just a private function
};
আপনি ধারণা পেতে। এখন দেখা যাক কীভাবে সমষ্টিগুলি বিশেষ। এগুলি, অ-সমষ্টিগত শ্রেণীর বিপরীতে কোঁকড়া ধনুর্বন্ধনী দিয়ে শুরু করা যেতে পারে {}
। এই আরম্ভের বাক্য গঠনটি সাধারণত অ্যারেগুলির জন্য পরিচিত এবং আমরা কেবল শিখেছি যে এগুলি সমষ্টি। সুতরাং, আসুন তাদের দিয়ে শুরু করা যাক।
Type array_name[n] = {a1, a2, …, am};
যদি (মি == ঢ)
আমি তম অ্যারের উপাদান একটি সঙ্গে সক্রিয়া করা হয় আমি
অন্যথায় যদি (মি <ঢ)
অ্যারের প্রথম মি উপাদানের একটি সঙ্গে সক্রিয়া করা হয় 1 , একটি 2 , ..., একটি মিটার এবং অন্যান্যn - m
উপাদান যদি সম্ভব হয় তবে মান-আরম্ভ হয় (শব্দটির ব্যাখ্যার জন্য নীচে দেখুন)
অন্যথায় যদি (এম> এন)
সংকলক
অন্য কোনও ত্রুটি জারি করবে (n এর মতো নির্দিষ্টভাবে নির্দিষ্ট না করা হয় তখনint a[] = {1, 2, 3};
এটি আকার হয় ) অ্যারে (এন) মিটার সমান হিসাবে ধরে নেওয়া হয়, তাইint a[] = {1, 2, 3};
সমানint a[3] = {1, 2, 3};
যখন স্কালে প্রকার (একটি অবজেক্ট bool
, int
, char
, double
, পয়েন্টার, ইত্যাদি) হয় মূল্য সক্রিয়া এটা মানে এটা দিয়ে সক্রিয়া করা হয় 0
যে টাইপ জন্য ( false
জন্য bool
, 0.0
জন্য double
ইত্যাদি)। যখন ব্যবহারকারী-ঘোষিত ডিফল্ট কনস্ট্রাক্টরের সাথে শ্রেণীর ধরণের কোনও অবজেক্টকে মান-আরম্ভ করা হয় তখন তার ডিফল্ট কনস্ট্রাক্টর বলা হয়। যদি ডিফল্ট কনস্ট্রাক্টর সুস্পষ্টভাবে সংজ্ঞায়িত হয় তবে সমস্ত ননস্ট্যাটিক সদস্য পুনরাবৃত্তভাবে মান-আরম্ভ হয় ized এই সংজ্ঞাটি যথার্থ এবং কিছুটা ভুল তবে এটির আপনাকে প্রাথমিক ধারণা দেওয়া উচিত। একটি রেফারেন্স মান-আরম্ভ করা যাবে না। একটি অ-সমষ্টিগত শ্রেণীর জন্য মান-সূচনা ব্যর্থ হতে পারে যদি উদাহরণস্বরূপ, শ্রেণীর উপযুক্ত ডিফল্ট নির্মাতা না থাকে।
অ্যারে প্রারম্ভিককরণের উদাহরণ:
class A
{
public:
A(int) {} //no default constructor
};
class B
{
public:
B() {} //default constructor available
};
int main()
{
A a1[3] = {A(2), A(1), A(14)}; //OK n == m
A a2[3] = {A(2)}; //ERROR A has no default constructor. Unable to value-initialize a2[1] and a2[2]
B b1[3] = {B()}; //OK b1[1] and b1[2] are value initialized, in this case with the default-ctor
int Array1[1000] = {0}; //All elements are initialized with 0;
int Array2[1000] = {1}; //Attention: only the first element is 1, the rest are 0;
bool Array3[1000] = {}; //the braces can be empty too. All elements initialized with false
int Array4[1000]; //no initializer. This is different from an empty {} initializer in that
//the elements in this case are not value-initialized, but have indeterminate values
//(unless, of course, Array4 is a global array)
int array[2] = {1, 2, 3, 4}; //ERROR, too many initializers
}
এখন দেখা যাক কীভাবে ব্রেস দিয়ে সমষ্টিগত ক্লাস শুরু করা যায়। বেশ একইভাবে। অ্যারে উপাদানগুলির পরিবর্তে আমরা অ-স্থিতিশীল ডেটা সদস্যদের শ্রেণি সংজ্ঞাতে তাদের উপস্থিতির ক্রম হিসাবে সূচনা করব (তারা সংজ্ঞা অনুসারে সকলেই প্রকাশ্য)। সদস্যদের তুলনায় যদি কম ইনিশিয়ালাইজার থাকে তবে বাকীগুলি মান-আরম্ভ হয়। সুস্পষ্টভাবে আরম্ভ করা হয়নি এমন কোনও সদস্যের যদি মূল্য-আরম্ভ করা অসম্ভব হয় তবে আমরা একটি সংকলন-সময় ত্রুটি পাই। যদি প্রয়োজনের তুলনায় আরও প্রাথমিকের ব্যবস্থা থাকে তবে আমরা একটি সংকলন-সময় ত্রুটিও পাই।
struct X
{
int i1;
int i2;
};
struct Y
{
char c;
X x;
int i[2];
float f;
protected:
static double d;
private:
void g(){}
};
Y y = {'a', {10, 20}, {20, 30}};
উপরের উদাহরণে y.c
সঙ্গে সক্রিয়া করা হয় 'a'
, y.x.i1
সঙ্গে 10
, y.x.i2
সঙ্গে 20
, y.i[0]
সঙ্গে 20
, y.i[1]
সঙ্গে 30
এবং y.f
মূল্য সক্রিয়া, যে, সঙ্গে সক্রিয়া করা হয় 0.0
। সুরক্ষিত স্ট্যাটিক সদস্য d
মোটেও আরম্ভ করা হয় না, কারণ এটি static
।
সামগ্রিক ইউনিয়নগুলি পৃথক পৃথক যে আপনি কেবল তাদের প্রথম সদস্যকে ধনুর্বন্ধনী দিয়ে শুরু করতে পারেন। আমি মনে করি আপনি ইউনিয়নগুলি ব্যবহারের বিষয়ে বিবেচনা করার জন্য যদি আপনি সি ++ তে যথেষ্ট উন্নত হন (তাদের ব্যবহার খুব বিপজ্জনক হতে পারে এবং সাবধানতার সাথে চিন্তা করা উচিত) তবে আপনি নিজেরাই স্ট্যান্ডার্ডে ইউনিয়নগুলির বিধিগুলি সন্ধান করতে পারেন :)।
এখন আমরা যে সমষ্টি সম্পর্কে বিশেষ কী তা জানি, আসুন আমরা ক্লাসগুলির উপরের বিধিনিষেধগুলি বোঝার চেষ্টা করি; তারা কেন সেখানে আছে। আমাদের বুঝতে হবে যে ধনুর্বন্ধনী দিয়ে সদস্যগত সূচনা বলতে বোঝায় যে শ্রেণি তার সদস্যদের যোগফল ছাড়া আর কিছুই নয়। যদি কোনও ব্যবহারকারী-সংজ্ঞায়িত কনস্ট্রাক্টর উপস্থিত থাকে তবে এর অর্থ হ'ল সদস্যকে আরম্ভ করার জন্য ব্যবহারকারীর কিছু অতিরিক্ত কাজ করা দরকার তাই ব্রেস আরম্ভটি ভুল হবে। ভার্চুয়াল ফাংশন উপস্থিত থাকলে, এর অর্থ এই যে এই শ্রেণীর অবজেক্টগুলির (বেশিরভাগ বাস্তবায়নের উপর) বর্গের তথাকথিত vtable এর পয়েন্টার রয়েছে, যা কনস্ট্রাক্টরে সেট করা আছে, তাই ব্রেস-আরম্ভকরণ অপর্যাপ্ত হবে fficient আপনি ব্যায়াম হিসাবে একইভাবে বাকি নিষেধাজ্ঞাগুলি বুঝতে পারেন :)।
সমষ্টি সম্পর্কে যথেষ্ট। এখন আমরা বুদ্ধিমানের, পিওডিগুলিতে প্রকারের একটি কঠোর সেট সংজ্ঞায়িত করতে পারি
সি ++ স্ট্যান্ডার্ড ( সি ++ 03 9 §4 ) থেকে আনুষ্ঠানিক সংজ্ঞা :
একটি পিওডি-স্ট্রাক্ট একটি সামগ্রিক শ্রেণি যা নন-পিওডি-স্ট্রাক্ট, নন-পড-ইউনিয়ন (বা এই জাতীয় ধরণের অ্যারে) বা রেফারেন্সের কোনও স্থিতিশীল ডেটা সদস্য নেই এবং এর কোনও ব্যবহারকারী-সংজ্ঞায়িত অনুলিপি অ্যাসাইনমেন্ট অপারেটর এবং নেই ব্যবহারকারী-সংজ্ঞায়িত ডেস্ট্রাক্টর। একইভাবে, একটি পড-ইউনিয়ন একটি সামগ্রিক ইউনিয়ন যার কোনও ধরণের নন-পিওডি-স্ট্রাক্ট, নন-পিওডি-ইউনিয়ন (বা এই জাতীয় ধরণের অ্যারে) বা রেফারেন্সের কোনও স্থিতিশীল ডেটা সদস্য নেই এবং এতে কোনও ব্যবহারকারী-সংজ্ঞায়িত অনুলিপি অ্যাসাইনমেন্ট অপারেটর নেই has এবং কোনও ব্যবহারকারী-সংজ্ঞায়িত ডেস্ট্রাক্টর নেই। একটি পিওডি ক্লাস এমন একটি শ্রেণি যা হয় একটি পিওডি-কাঠামো বা একটি পিওডি-ইউনিয়ন।
বাহ, এটি পার্স করা আরও কঠিন, তাই না? :) আসুন ইউনিয়নগুলি ছেড়ে দেওয়া যাক (উপরের মতো একই ভিত্তিতে) এবং কিছুটা পরিষ্কার পদ্ধতিতে পুনরায় প্রতিস্থাপন করুন:
একটি সামগ্রিক শ্রেণিকে পিওড বলা হয় যদি এটির কোনও ব্যবহারকারী-সংজ্ঞায়িত অনুলিপি-অ্যাসাইনমেন্ট অপারেটর এবং ডেস্ট্রাক্টর না থাকে এবং এর ননস্ট্যাটিক সদস্যগুলির মধ্যে কোনওটিই নন-পিওডি ক্লাস, নন-পিওডি অ্যারে বা রেফারেন্স নয়।
এই সংজ্ঞাটি কি বোঝায়? (আমি কি উল্লেখ করেছি যে পিওডির অর্থ সমতল ওল্ড ডেটা ?)
উদাহরণ:
struct POD
{
int x;
char y;
void f() {} //no harm if there's a function
static std::vector<char> v; //static members do not matter
};
struct AggregateButNotPOD1
{
int x;
~AggregateButNotPOD1() {} //user-defined destructor
};
struct AggregateButNotPOD2
{
AggregateButNotPOD1 arrOfNonPod[3]; //array of non-POD class
};
পিওড-ক্লাস, পিওডি-ইউনিয়ন, স্কেলার প্রকার এবং এ জাতীয় ধরণের অ্যারেগুলিকে সম্মিলিতভাবে পিওডি-প্রকারগুলি বলা হয় ।
পিওডিগুলি বিভিন্ন উপায়ে বিশেষ। আমি কিছু উদাহরণ প্রদান করব।
পিওড-ক্লাসগুলি সি স্ট্রাক্টগুলির নিকটতম। তাদের বিপরীতে, পিওডি-র সদস্য ফাংশন এবং স্বেচ্ছাসেবী স্থিতিশীল সদস্য থাকতে পারে, তবে এই দুজনের কোনওটিরই অবজেক্টের মেমরি লেআউট পরিবর্তন হয় না। সুতরাং আপনি যদি আরও কম সংখ্যক পোর্টেবল ডায়নামিক লাইব্রেরি লিখতে চান যা সি এবং এমনকি নেট থেকেও ব্যবহার করা যায় তবে আপনার সমস্ত রফতানি ফাংশনগুলি কেবলমাত্র পড-পর্বের পরামিতিগুলি গ্রহণ এবং ফেরত দেওয়ার চেষ্টা করা উচিত।
নন-পিওডি শ্রেণীর ধরণের অবজেক্টগুলির জীবনকাল শুরু হয় যখন কনস্ট্রাক্টর শেষ হয়ে যায় এবং ডেস্ট্রাক্টর শেষ হয়ে গেলে শেষ হয়। পিওডি ক্লাসগুলির জন্য, যখন স্টোরেজটি প্রকাশিত বা পুনরায় ব্যবহার করা হয় তখন অবজেক্টের স্টোরেজ দখল করা হয় এবং শেষ হয় তখন জীবনকাল শুরু হয়।
পিওডি ধরণের জিনিসগুলির জন্য এটি স্ট্যান্ডার্ডের দ্বারা গ্যারান্টিযুক্ত যে আপনি যখন memcpy
আপনার অবজেক্টের বিষয়বস্তুগুলি চর বা স্বাক্ষরবিহীন চরের একটি অ্যারে রূপান্তর করবেন এবং তারপরে memcpy
সামগ্রীগুলি আপনার বস্তুর মধ্যে ফিরে আসবে তখন অবজেক্টটি তার মূল মানটি ধরে রাখবে। নোট করুন যে নন-পিওডি ধরণের জিনিসগুলির জন্য এমন কোনও গ্যারান্টি নেই। এছাড়াও, আপনি নিরাপদে পিওডি অবজেক্টগুলির সাথে অনুলিপি করতে পারেন memcpy
। নিম্নলিখিত উদাহরণটি ধরে নিয়েছে টি একটি পড-প্রকার:
#define N sizeof(T)
char buf[N];
T obj; // obj initialized to its original value
memcpy(buf, &obj, N); // between these two calls to memcpy,
// obj might be modified
memcpy(&obj, buf, N); // at this point, each subobject of obj of scalar type
// holds its original value
গেটো স্টেটমেন্ট আপনি জানেন যে, এটি বেআইনী (সংকলকটি একটি ত্রুটি জারি করা উচিত) এমন একটি বিন্দু থেকে গোটোর মাধ্যমে একটি লাফ তৈরি করা যেখানে কিছু ভেরিয়েবল এখনও এমন একটি বিন্দুতে অবধি ছিল না যেখানে এটি ইতিমধ্যে সুযোগে রয়েছে। এই সীমাবদ্ধতাটি কেবল তখনই প্রযোজ্য যখন ভেরিয়েবলটি নন-পিওডি টাইপের হয়। নীচের উদাহরণে f()
দূর্গঠিত যেখানে g()
সুগঠিত রয়েছে। নোট করুন যে মাইক্রোসফ্ট সংকলক এই নিয়মের সাথে খুব উদার - এটি উভয় ক্ষেত্রেই একটি সতর্কতা জারি করে।
int f()
{
struct NonPOD {NonPOD() {}};
goto label;
NonPOD x;
label:
return 0;
}
int g()
{
struct POD {int i; char c;};
goto label;
POD x;
label:
return 0;
}
এটি গ্যারান্টিযুক্ত যে কোনও পিওডি অবজেক্টের শুরুতে কোনও প্যাডিং থাকবে না। অন্য কথায়, যদি একটি শুঁটি ক্লাসের একজন প্রথম সদস্য টাইপ টি হল, আপনি নিরাপদে পারেন reinterpret_cast
থেকে A*
থেকে T*
এবং পয়েন্টার পেতে প্রথম সদস্য এবং তদ্বিপরীত।
তালিকা এবং উপর যায়…
একটি পিওডি ঠিক কী তা বোঝা গুরুত্বপূর্ণ কারণ অনেকগুলি ভাষা বৈশিষ্ট্য যেমন আপনি দেখেন, তাদের জন্য আলাদা আচরণ করে।
private:
যথাযথ হিসাবে সন্নিবেশ করান ): struct A { int const a; };
তবে A()
এটির সুষ্ঠুভাবে গঠন করা হয়, এমনকি যদি A
এর ডিফল্ট কনস্ট্রাক্টরের সংজ্ঞাটি খারাপ থাকে।
একটি সামগ্রীর মানক সংজ্ঞাটি কিছুটা পরিবর্তিত হয়েছে, তবে এটি এখনও বেশ একইরকম:
সমষ্টিগত হ'ল একটি অ্যারে বা একটি ক্লাস (ক্লজ 9) যার সাথে ব্যবহারকারী-সরবরাহকৃত কনস্ট্রাক্টর (12.1) নেই, স্থিতিশীল ডেটা সদস্যদের (9.2) কোনও ব্রেস-বা-সমমান-আরম্ভকারী নেই, কোনও ব্যক্তিগত বা সুরক্ষিত অ-স্থিতিশীল ডেটা সদস্যদের নয় ( ধারা 11), কোনও বেস ক্লাস (ক্লজ 10), এবং কোনও ভার্চুয়াল ফাংশন (10.3) নেই।
ঠিক আছে, কি পরিবর্তন হয়েছে?
পূর্বে, একটি সামগ্রীতে কোনও ব্যবহারকারী-ঘোষিত কনস্ট্রাক্টর থাকতে পারে না , তবে এখন এটিতে ব্যবহারকারী-সরবরাহকারী কনস্ট্রাক্টর থাকতে পারে না । পার্থক্য আছে কি? হ্যাঁ, রয়েছে, কারণ এখন আপনি নির্ধারক ঘোষণা করতে পারেন এবং সেগুলি ডিফল্ট করতে পারেন :
struct Aggregate {
Aggregate() = default; // asks the compiler to generate the default implementation
};
এটি এখনও সামগ্রিক কারণ কোনও কনস্ট্রাক্টর (বা কোনও বিশেষ সদস্য ফাংশন) যা প্রথম ঘোষণায় খেলাপি হয়ে থাকে তা ব্যবহারকারী দ্বারা সরবরাহ করা হয় না।
এখন সামগ্রিক অ স্থিতিশীল ডেটা সদস্যদের জন্য কোনও ব্রেস-বা-সমমান-আরম্ভকারী থাকতে পারে না । এটার মানে কি? ঠিক আছে, কারণ এটি এই নতুন স্ট্যান্ডার্ডের সাথে, আমরা সরাসরি ক্লাসে সদস্যদের শুরু করতে পারি:
struct NotAggregate {
int x = 5; // valid in C++11
std::vector<int> s{1,2,3}; // also valid
};
এই বৈশিষ্ট্যটি ব্যবহার করে ক্লাস আর আর একটি সামগ্রীতে পরিণত হয় না কারণ এটি মূলত আপনার নিজের ডিফল্ট কনস্ট্রাক্টর সরবরাহের সমতুল্য।
সুতরাং, একটি সামগ্রিক কি মোটেও খুব বেশি পরিবর্তন হয়নি। এটি এখনও একই বৈশিষ্ট্যটি নতুন বৈশিষ্ট্যের সাথে খাপ খাইয়ে নিয়েছে।
পিওডিগুলি প্রচুর পরিবর্তনের মধ্য দিয়ে গেছে। পিওডি সম্পর্কে পূর্ববর্তী প্রচুর বিধিগুলি এই নতুন স্ট্যান্ডার্ডে শিথিল করা হয়েছিল এবং স্ট্যান্ডার্ডে যেভাবে সংজ্ঞা দেওয়া হয় তা আমূল পরিবর্তন করা হয়েছিল।
পিওডের ধারণাটি মূলত দুটি স্বতন্ত্র বৈশিষ্ট্য ক্যাপচার করা:
এ কারণে সংজ্ঞাটি দুটি স্বতন্ত্র ধারণার মধ্যে বিভক্ত হয়েছে: তুচ্ছ শ্রেণি এবং মান-বিন্যাস শ্রেণি, কারণ এগুলি পিওডির চেয়ে বেশি কার্যকর। আরও নির্দিষ্ট তুচ্ছ এবং স্ট্যান্ডার্ড-বিন্যাস ধারণাগুলি পছন্দ করে স্ট্যান্ডার্ডটি খুব কমই POD শব্দটি ব্যবহার করে ।
নতুন সংজ্ঞাটি মূলত বলেছে যে একটি পিওডি একটি শ্রেণি যা উভয়ই তুচ্ছ এবং মানক-লেআউট রয়েছে এবং এই সম্পত্তিটি অবশ্যই সমস্ত অ স্থিতিশীল ডেটা সদস্যদের জন্য পুনরাবৃত্তভাবে ধরে রাখতে হবে:
একটি পিওডি স্ট্রাক্ট একটি নন-ইউনিয়ন শ্রেণি যা উভয়ই তুচ্ছ শ্রেণি এবং মান-লেআউট শ্রেণি, এবং নন-পিওডি স্ট্রাক্ট, নন-পিওডি ইউনিয়ন (বা এই জাতীয় ধরণের অ্যারে) কোনও স্ট্যাটাস ডেটা সদস্য নয়। একইভাবে, একটি পিওডি ইউনিয়ন এমন একটি ইউনিয়ন যা উভয় তুচ্ছ শ্রেণি এবং একটি মান বিন্যাস শ্রেণি, এবং নন-পিওডি স্ট্রাক্ট, নন-পিওডি ইউনিয়ন (বা এই জাতীয় ধরণের অ্যারে) কোনও স্ট্যাটাস ডেটা সদস্য নেই। একটি পিওডি ক্লাস এমন একটি শ্রেণি যা হয় একটি পিওডি স্ট্রাক্ট বা পিওডি ইউনিয়ন।
আসুন পৃথকভাবে এই দুটি বৈশিষ্ট্যের প্রত্যেকটির উপরে যান।
তুচ্ছটি হ'ল উপরে বর্ণিত প্রথম সম্পত্তি: তুচ্ছ শ্রেণি স্থির সূচনা সমর্থন করে। যদি কোনও শ্রেণি তুচ্ছভাবে অনুলিপিযোগ্য (তুচ্ছ শ্রেণির একটি সুপারসেট) হয় তবে জায়গাটির মতো তার প্রতিনিধিত্বটি কপিরাইট memcpy
করা ভাল এবং ঠিক একই ফলাফলের আশা করা যায় expect
মান নিম্নরূপে একটি তুচ্ছ শ্রেণীর সংজ্ঞা দেয়:
তুচ্ছভাবে অনুলিপিযোগ্য শ্রেণি এমন একটি শ্রেণি যা:
- কোনও তুচ্ছ কপি নির্মাণকারী (12.8) নেই,
- এর কোনও তুচ্ছ তাত্ক্ষণিক চালক (12.8) নেই,
- এর কোনও তুচ্ছ কপির অ্যাসাইনমেন্ট অপারেটর নেই (13.5.3, 12.8),
- এর কোনও তুচ্ছ ট্র্যাভেল অ্যাসাইনমেন্ট অপারেটর নেই (13.5.3, 12.8), এবং
- এর একটি তুচ্ছ ডেস্ট্রাক্টর (12.4) রয়েছে।
তুচ্ছ শ্রেণি একটি শ্রেণি যা একটি তুচ্ছ ডিফল্ট কনস্ট্রাক্টর (12.1) থাকে এবং তুচ্ছভাবে অনুলিপিযোগ্য হয়।
[ দ্রষ্টব্য: বিশেষত, একটি তুচ্ছভাবে অনুলিপিযোগ্য বা তুচ্ছ শ্রেণীর ভার্চুয়াল ফাংশন বা ভার্চুয়াল বেস ক্লাস নেই। অন্তর্ভুক্ত নোট ]
সুতরাং, এই সমস্ত তুচ্ছ এবং অপ্রয়োজনীয় জিনিস কি?
দশম শ্রেণির জন্য একটি অনুলিপি / মুভ কনস্ট্রাক্টর যদি এটি ব্যবহারকারীর দ্বারা সরবরাহ করা না হয় এবং যদি তা ক্ষুদ্র হয়
- দশম শ্রেণির কোনও ভার্চুয়াল ফাংশন (10.3) এবং ভার্চুয়াল বেস ক্লাস (10.1) নেই এবং
- প্রতিটি প্রত্যক্ষ বেস শ্রেণীর সাবোবজেক্টটি অনুলিপি / সরানোর জন্য নির্বাচিত নির্বাচিতটি তুচ্ছ এবং এবং
- এক্স-এর প্রতিটি অ-স্থিতিশীল ডেটা সদস্যের জন্য যা শ্রেণীর ধরণের (বা এর অ্যারে) থাকে, সেই সদস্যের অনুলিপি / সরানোর জন্য নির্বাচিত নির্বাচক তুচ্ছ;
অন্যথায় অনুলিপি / মুভ নির্মাণকারী।
মূলত এর অর্থ হ'ল কোনও অনুলিপি বা মুভ কনস্ট্রাক্টর যদি এটি ব্যবহারকারীর দ্বারা সরবরাহ করা না হয় তবে শ্রেণীর কোনও ভার্চুয়াল থাকে না এবং এই সম্পত্তিটি শ্রেণীর সমস্ত সদস্য এবং বেস বর্গের জন্য পুনরাবৃত্তভাবে ধারন করে।
তুচ্ছ কপি / মুভ অ্যাসাইনমেন্ট অপারেটরের সংজ্ঞাটি খুব অনুরূপ, কেবল "কন্সট্রাক্টর" শব্দটির পরিবর্তে "এসাইনমেন্ট অপারেটর" ব্যবহার করে।
একটি তুচ্ছ ডেস্ট্রাক্টরেরও অনুরূপ সংজ্ঞা রয়েছে, যুক্ত হওয়া সীমাবদ্ধতার সাথে এটি ভার্চুয়াল হতে পারে না।
তবুও ত্রুটিপূর্ণ ডিফল্ট কনস্ট্রাক্টরদের জন্য আর একটি অনুরূপ নিয়ম উপস্থিত রয়েছে, বর্গ-বর্গ -সমান-আরম্ভকারী সহ ক্লাসে অ স্থিতিশীল ডেটা সদস্য থাকলে শ্রেণিকের ক্ষেত্রে তুচ্ছ-তুচ্ছ নয় , যা আমরা উপরে দেখেছি।
সবকিছু পরিষ্কার করার জন্য এখানে কয়েকটি উদাহরণ রয়েছে:
// empty classes are trivial
struct Trivial1 {};
// all special members are implicit
struct Trivial2 {
int x;
};
struct Trivial3 : Trivial2 { // base class is trivial
Trivial3() = default; // not a user-provided ctor
int y;
};
struct Trivial4 {
public:
int a;
private: // no restrictions on access modifiers
int b;
};
struct Trivial5 {
Trivial1 a;
Trivial2 b;
Trivial3 c;
Trivial4 d;
};
struct Trivial6 {
Trivial2 a[23];
};
struct Trivial7 {
Trivial6 c;
void f(); // it's okay to have non-virtual functions
};
struct Trivial8 {
int x;
static NonTrivial1 y; // no restrictions on static members
};
struct Trivial9 {
Trivial9() = default; // not user-provided
// a regular constructor is okay because we still have default ctor
Trivial9(int x) : x(x) {};
int x;
};
struct NonTrivial1 : Trivial3 {
virtual void f(); // virtual members make non-trivial ctors
};
struct NonTrivial2 {
NonTrivial2() : z(42) {} // user-provided ctor
int z;
};
struct NonTrivial3 {
NonTrivial3(); // user-provided ctor
int w;
};
NonTrivial3::NonTrivial3() = default; // defaulted but not on first declaration
// still counts as user-provided
struct NonTrivial5 {
virtual ~NonTrivial5(); // virtual destructors are not trivial
};
মান- বিন্যাস দ্বিতীয় সম্পত্তি। স্ট্যান্ডার্ডটি উল্লেখ করে যে এগুলি অন্যান্য ভাষার সাথে যোগাযোগের জন্য দরকারী, এবং এটি কারণ একটি স্ট্যান্ডার্ড-লেআউট শ্রেণিতে সমমানের সি স্ট্রাক্ট বা ইউনিয়নের একই মেমরি লেআউট রয়েছে।
এটি এমন আরও একটি সম্পত্তি যা অবশ্যই সদস্যদের এবং সমস্ত বেস ক্লাসগুলির জন্য অবশ্যই পুনরাবৃত্ত হতে হবে। এবং যথারীতি কোনও ভার্চুয়াল ফাংশন বা ভার্চুয়াল বেস ক্লাস অনুমোদিত নয়। এটি সি এর সাথে লেআউটটিকে বেমানান করে তুলবে layout
এখানে একটি স্বচ্ছন্দ নিয়ম হ'ল স্ট্যান্ডার্ড-লেআউট ক্লাসগুলিতে একই অ্যাক্সেস নিয়ন্ত্রণ সহ সমস্ত অ-স্থিতিশীল ডেটা সদস্য থাকতে হবে। পূর্বে এগুলি সর্বজনীন হতে হত তবে এখন পর্যন্ত আপনি এগুলি ব্যক্তিগত বা সুরক্ষিত করতে পারবেন যতক্ষণ না তারা সমস্ত ব্যক্তিগত বা সমস্ত সুরক্ষিত থাকে।
উত্তরাধিকার ব্যবহার করার সময়, শুধুমাত্র একটি পুরো উত্তরাধিকার গাছের মধ্যে শ্রেণিতে স্থিতিশীল ডেটা সদস্য থাকতে পারে এবং প্রথম নন-স্ট্যাটিক ডেটা সদস্য বেস বর্গ ধরণের হতে পারে না (এটি আলিয়াসিংয়ের নিয়মগুলি ভেঙে ফেলতে পারে), অন্যথায়, এটি স্ট্যান্ডার্ড নয়- লেআউট ক্লাস।
স্ট্যান্ডার্ড পাঠ্যে সংজ্ঞাটি এভাবে যায়:
একটি স্ট্যান্ডার্ড-লেআউট ক্লাস এমন একটি ক্লাস যা:
- প্রকারের অ-স্ট্যান্ডার্ড-লেআউট শ্রেণীর (বা এই জাতীয় ধরণের অ্যারে) বা রেফারেন্সের কোনও অ-স্থিতিশীল ডেটা সদস্য নেই,
- এর কোনও ভার্চুয়াল ফাংশন (10.3) এবং ভার্চুয়াল বেস ক্লাস (10.1) নেই,
- সমস্ত অ স্থিতিশীল ডেটা সদস্যদের জন্য একই অ্যাক্সেস নিয়ন্ত্রণ (ধারা 11) রয়েছে,
- এর কোনও মানক-বিন্যাসের বেস ক্লাস নেই,
- হয় সর্বাধিক উদ্ভূত শ্রেণিতে এবং অ স্থিতিশীল ডেটা সদস্য সহ সর্বাধিক একটি বেস ক্লাসে কোনও অ স্থিতিশীল ডেটা সদস্য নেই, বা অ-স্থিতিশীল ডেটা সদস্য সহ কোনও বেস ক্লাস নেই, এবং
- প্রথম অ-স্থিতিশীল ডেটা সদস্য হিসাবে একই ধরণের কোনও বেস ক্লাস নেই।
একটি স্ট্যান্ডার্ড-লেআউট স্ট্রাক্ট একটি স্ট্যান্ডার্ড-লেআউট ক্লাস যা ক্লাস-কী স্ট্রাক্ট বা ক্লাস-কী শ্রেণীর সাথে সংজ্ঞায়িত হয়।
একটি স্ট্যান্ডার্ড-লেআউট ইউনিয়ন ক্লাস-কী ইউনিয়নের সাথে সংজ্ঞায়িত একটি স্ট্যান্ডার্ড-লেআউট ক্লাস।
[ দ্রষ্টব্য: অন্যান্য প্রোগ্রামিং ভাষায় লিখিত কোডের সাথে যোগাযোগের জন্য স্ট্যান্ডার্ড-লেআউট ক্লাসগুলি কার্যকর। তাদের বিন্যাসটি 9.2-এ নির্দিষ্ট করা হয়েছে। অন্তর্ভুক্ত নোট ]
এবং এর কয়েকটি উদাহরণ দেখুন।
// empty classes have standard-layout
struct StandardLayout1 {};
struct StandardLayout2 {
int x;
};
struct StandardLayout3 {
private: // both are private, so it's ok
int x;
int y;
};
struct StandardLayout4 : StandardLayout1 {
int x;
int y;
void f(); // perfectly fine to have non-virtual functions
};
struct StandardLayout5 : StandardLayout1 {
int x;
StandardLayout1 y; // can have members of base type if they're not the first
};
struct StandardLayout6 : StandardLayout1, StandardLayout5 {
// can use multiple inheritance as long only
// one class in the hierarchy has non-static data members
};
struct StandardLayout7 {
int x;
int y;
StandardLayout7(int x, int y) : x(x), y(y) {} // user-provided ctors are ok
};
struct StandardLayout8 {
public:
StandardLayout8(int x) : x(x) {} // user-provided ctors are ok
// ok to have non-static data members and other members with different access
private:
int x;
};
struct StandardLayout9 {
int x;
static NonStandardLayout1 y; // no restrictions on static members
};
struct NonStandardLayout1 {
virtual f(); // cannot have virtual functions
};
struct NonStandardLayout2 {
NonStandardLayout1 X; // has non-standard-layout member
};
struct NonStandardLayout3 : StandardLayout1 {
StandardLayout1 x; // first member cannot be of the same type as base
};
struct NonStandardLayout4 : StandardLayout3 {
int z; // more than one class has non-static data members
};
struct NonStandardLayout5 : NonStandardLayout3 {}; // has a non-standard-layout base class
এই নতুন নিয়মের সাহায্যে এখন আরও অনেক ধরণের পিওডি হতে পারে। এমনকি কোনও প্রকারটি পিওডি না হলেও আমরা কিছু পিওডি বৈশিষ্ট্য আলাদাভাবে নিতে পারি (এটি যদি তুচ্ছ বা মানক বিন্যাসের মধ্যে কেবল একটি হয়)।
হেডারে এই বৈশিষ্ট্যগুলি পরীক্ষা করার জন্য স্ট্যান্ডার্ড লাইব্রেরির বৈশিষ্ট্য রয়েছে <type_traits>
:
template <typename T>
struct std::is_pod;
template <typename T>
struct std::is_trivial;
template <typename T>
struct std::is_trivially_copyable;
template <typename T>
struct std::is_standard_layout;
আমরা রেফারেন্সের জন্য খসড়া সি ++ 14 মান উল্লেখ করতে পারি।
এটি বিভাগের 8.5.1
সমষ্টিগুলিতে আচ্ছাদিত যা আমাদের নিম্নলিখিত সংজ্ঞা দেয়:
একটি সমষ্টি হ'ল একটি অ্যারে বা একটি ক্লাস (ক্লজ 9) যার সাথে কোনও ব্যবহারকারী সরবরাহিত কনস্ট্রাক্টর (12.1) নেই, কোনও ব্যক্তিগত বা সুরক্ষিত নন-স্ট্যাটিক ডেটা সদস্য নয় (ক্লজ 11), কোনও বেস ক্লাস (ক্লজ 10) এবং ভার্চুয়াল ফাংশন নেই (10.3 )।
একমাত্র পরিবর্তনটি এখন শ্রেণীর সদস্য প্রারম্ভিককে যুক্ত করছে কোনও শ্রেণিকে অ-সমষ্টিগত করে না। সুতরাং সদস্য ইন-পেস ইনিশিয়ালাইজার সহ ক্লাসগুলির জন্য সি ++ 11 সমষ্টিগত সূচনা থেকে নিম্নলিখিত উদাহরণ :
struct A
{
int a = 3;
int b = 3;
};
সি ++ 11 তে মোট ছিল না তবে এটি সি ++ 14 এ রয়েছে। এই পরিবর্তনটি N3605 এ আচ্ছাদিত রয়েছে : সদস্য আরম্ভকারী এবং সমষ্টি , যার নিম্নলিখিত বিমূর্তি রয়েছে:
সমাহার সূচনা এবং সদস্য-প্রাথমিককরণ একসাথে কাজ না করার বিষয়ে বাজার্ন স্ট্রস্ট্রপ এবং রিচার্ড স্মিথ একটি ইস্যু উত্থাপন করেছিলেন। এই কাগজটিতে স্মিথের প্রস্তাবিত শব্দ গ্রহণ করে সমস্যাটি সমাধানের প্রস্তাব দেওয়া হয়েছে যা এমন একটি বিধিনিষেধকে সরিয়ে দেয় যে সমষ্টিগুলিতে সদস্য-প্রাথমিককরণকারী থাকতে পারে না।
পিওডি ( প্লেইন পুরাতন ডেটা ) স্ট্রাক্টের সংজ্ঞাটি 9
ক্লাস ক্লাসে আচ্ছাদিত রয়েছে যা বলে:
একটি পিওডি কাঠামো 110 হ'ল একটি নন-ইউনিয়ন শ্রেণি যা উভয়ই তুচ্ছ শ্রেণি এবং স্ট্যান্ডার্ড-লেআউট শ্রেণি, এবং নন-পিওডি স্ট্রাক্ট, নন-পিওডি ইউনিয়ন (বা এই জাতীয় ধরণের অ্যারে) কোনও স্ট্যাটাস ডেটা সদস্য নেই। একইভাবে, একটি পিওডি ইউনিয়ন এমন একটি ইউনিয়ন যা উভয় তুচ্ছ শ্রেণি এবং একটি মান-লেআউট শ্রেণি, এবং প্রকার নন-পিওডি স্ট্রাক্ট, নন-পড ইউনিয়ন (বা এই জাতীয় ধরণের অ্যারে) এর কোনও স্থিতিশীল ডেটা সদস্য নেই। একটি পিওডি ক্লাস এমন একটি শ্রেণি যা হয় একটি পিওডি স্ট্রাক্ট বা পিওডি ইউনিয়ন।
যা সি ++ 11 এর মতো একই শব্দযুক্ত।
মন্তব্যে উল্লিখিত হিসাবে পড স্ট্যান্ডার্ড-বিন্যাসের সংজ্ঞা উপর নির্ভর করে এবং এটি সি ++ ১৪ এর জন্য পরিবর্তিত হয়েছিল তবে এটি ত্রুটি প্রতিবেদনের মাধ্যমে যা সি ++ 14 এর পরে প্রয়োগ হয়েছিল।
তিন জন ডিআর ছিলেন:
সুতরাং স্ট্যান্ডার্ড-লেআউটটি এই প্রাক সি ++ 14 থেকে গেছে:
একটি স্ট্যান্ডার্ড-লেআউট ক্লাস এমন একটি ক্লাস যা:
- (.1.১) এর অ-মানক-লেআউট শ্রেণীর টাইপ (বা এই জাতীয় ধরণের অ্যারে) বা রেফারেন্সের কোনও অ-স্থিতিশীল ডেটা সদস্য নেই,
- (.2.২) এর কোনও ভার্চুয়াল ফাংশন ([class.virtual]) এবং কোনও ভার্চুয়াল বেস ক্লাস ([class.mi]) নেই,
- (.3.৩) সমস্ত অ স্থিতিশীল ডেটা সদস্যদের জন্য একই অ্যাক্সেস নিয়ন্ত্রণ (ক্লজ [শ্রেণী.অ্যাক্সেস]) রয়েছে,
- (7.4) এর কোনও অ-মানক-বিন্যাসের বেস শ্রেণি নেই,
- (.5.৫) হয় সর্বাধিক উত্সযুক্ত শ্রেণিতে এবং অ স্থিতিশীল ডেটা সদস্য সহ একটি বেস ক্লাসে কোনও অ স্থিতিশীল ডেটা সদস্য নেই, বা অ স্থিতিশীল ডেটা সদস্য সহ কোনও বেস ক্লাস নেই, এবং
- (.6..6) প্রথম অ-স্থিতিশীল ডেটা সদস্য হিসাবে একই ধরণের কোনও বেস ক্লাস নেই 10
করার সি ++ 14 এ এই :
একটি ক্লাস এস একটি স্ট্যান্ডার্ড-লেআউট শ্রেণি যদি এটি হয়:
- (৩.১) এর অ-স্ট্যান্ডার্ড ডেটা সদস্য প্রকারের নন-স্ট্যান্ডার্ড-লেআউট শ্রেণীর (বা এই জাতীয় ধরণের অ্যারে) বা রেফারেন্স নেই,
- (৩.২) এর কোন ভার্চুয়াল ফাংশন এবং ভার্চুয়াল বেস ক্লাস নেই,
- (3.3) এর সমস্ত অ স্থিতিশীল ডেটা সদস্যদের জন্য একই অ্যাক্সেস নিয়ন্ত্রণ রয়েছে,
- (3.4) এর কোনও অ-মানক-বিন্যাস বেস শ্রেণি নেই,
- (3.5) কোনও প্রদত্ত প্রকারের সর্বাধিক এক বেস শ্রেণীর সাবোবজেক্ট রয়েছে,
- (৩.6) ক্লাসে সমস্ত অ স্থিতিশীল ডেটা সদস্য এবং বিট-ফিল্ড রয়েছে এবং এর বেস ক্লাসটি একই শ্রেণিতে প্রথম ঘোষিত হয়েছে, এবং
- (৩.7) বেস বর্গ হিসাবে সেট এম (এস) এর কোনও উপাদান নেই, যেখানে কোনও ধরণের এক্স, এম (এক্স) নিম্নরূপে সংজ্ঞায়িত করা হয়েছে। ১০০ [দ্রষ্টব্য: এম (এক্স) এর ধরণের সেট এক্স-এর শূন্য অফসেটে থাকা সমস্ত অ-বেস-ক্লাস সাববোজেক্টগুলি - শেষ নোট]
- (৩. 3..১) এক্সটি যদি কোনও অ-ইউনিয়ন শ্রেণীর ধরণের হয় (সম্ভবত উত্তরাধিকার সূত্রে প্রাপ্ত) অ স্থির ডেটা সদস্য নয়, সেট এম (এক্স) খালি রয়েছে।
- (7..2.২) এক্স যদি কোনও নন-ইউনিয়ন শ্রেণীর ধরণের হয় তবে এটি কোনও শূন্য আকারের নয় এমন এক্স0 টাইপের নন-স্ট্যাটিক ডেটা মেম্বার বা এক্স এর প্রথম অ স্থির ডেটা সদস্য (যেখানে বলা হয়েছে সদস্য কোনও বেনাম ইউনিয়ন হতে পারে) ), সেট এম (এক্স) এক্স0 এবং এম (এক্স0) এর উপাদানগুলি নিয়ে গঠিত।
- (7..3.৩) এক্সটি যদি ইউনিয়নের ধরণ থাকে তবে সেট এম (এক্স) হ'ল সমস্ত এম (ইউআই) এবং সমস্ত ইউআই সমন্বিত সেট যেখানে প্রতিটি ইউআই এক্সের অষ্টিক স্থায়ী ডেটা সদস্যের টাইপ ।
- (7.7.৪) যদি এক্স টাইপের ধরণের এক্সের সাথে অ্যারে টাইপ করে থাকে তবে সেট এম (এক্স) এক্স এবং এম (এক্স) এর উপাদানগুলি নিয়ে গঠিত।
- (3.7.5) এক্সটি যদি একটি শ্রেণিবদ্ধ, অ-অ্যারে টাইপ হয় তবে সেট এম (এক্স) খালি রয়েছে।
আপনি কি দয়া করে নিম্নলিখিত বিধিগুলি বিস্তারিতভাবে বর্ণনা করতে পারেন:
আমি চেষ্টা করবো:
ক) স্ট্যান্ডার্ড-লেআউট ক্লাসে একই অ্যাক্সেস নিয়ন্ত্রণ সহ সমস্ত অ-স্থিতিশীল ডেটা সদস্য থাকতে হবে
যে সহজ: সমস্ত অ স্ট্যাটিক ডাটা সদস্যদের আবশ্যক সব হতেpublic
, private
অথবা protected
। আপনার কিছু না public
কিছু থাকতে পারেprivate
।
তাদের জন্য যুক্তিটি "স্ট্যান্ডার্ড লেআউট" এবং "স্ট্যান্ডার্ড বিন্যাস নয়" এর মধ্যে পার্থক্য রাখার যুক্তিতে চলে। যথা, কীভাবে স্মৃতিতে জিনিস রাখবে তা চয়ন করার স্বাধীনতা সংকলককে দেওয়া। এটি কেবল ভিটেবল পয়েন্টার সম্পর্কে নয়।
98 সালে যখন তারা সি ++ মানক করেছিলেন তখন লোকেরা কীভাবে এটি প্রয়োগ করবে তা তাদের মূলত ভবিষ্যদ্বাণী করতে হয়েছিল। সি ++ এর বিভিন্ন স্বাদের সাথে তাদের প্রয়োগের বেশ কিছুটা অভিজ্ঞতা থাকলেও তারা বিষয়গুলি সম্পর্কে নিশ্চিত ছিলেন না। সুতরাং তারা সাবধান হওয়ার সিদ্ধান্ত নিয়েছে: সংকলকগুলিকে যথাসম্ভব স্বাধীনতা দিন।
এজন্য সি ++ 98 এ POD এর সংজ্ঞাটি এত কঠোর। এটি বেশিরভাগ ক্লাসের সদস্য লেআউটটিতে সি ++ সংকলককে দুর্দান্ত অক্ষাংশ দিয়েছে। মূলত, পিওডি টাইপগুলি বিশেষ কেস হিসাবে চিহ্নিত করা হয়েছিল, এমন কিছু যা আপনি বিশেষভাবে কোনও কারণে লিখেছিলেন।
সি ++ 11 এ যখন কাজ করা হচ্ছিল তখন তাদের সংকলকগুলির সাথে আরও অনেক অভিজ্ঞতা ছিল। এবং তারা বুঝতে পেরেছিল যে ... সি ++ সংকলক লেখকরা সত্যিই অলস। তারা এই সব স্বাধীনতা ছিল, কিন্তু তারা করা হয়নি কি এটা নিয়ে কিছু।
স্ট্যান্ডার্ড বিন্যাসের নিয়মগুলি কমবেশি প্রচলিত অনুশীলনকে কোডিং করে: বেশিরভাগ সংকলকগুলিকে বাস্তবায়নের জন্য কিছু না আসলেই কিছু পরিবর্তন করতে হত না (সংশ্লিষ্ট ধরণের বৈশিষ্ট্যের জন্য সম্ভবত কিছু স্টাফের বাইরে)।
এখন, যখন public
/ এ আসে private
, জিনিসগুলি আলাদা। কোন সদস্যদের public
বনাম পুনরায় অর্ডার করার স্বাধীনতা ।private
পক্ষে বিশেষত ডিবাগিং বিল্ডগুলির ক্ষেত্রে গুরুত্বপূর্ণ। এবং যেহেতু স্ট্যান্ডার্ড বিন্যাসের বিষয়টি হ'ল অন্যান্য ভাষার সাথে সামঞ্জস্যতা রয়েছে তাই আপনার ডিবাগ বনাম রিলিজের ক্ষেত্রে লেআউটটি আলাদা হতে পারে না।
তারপরে এটি সত্য যে এটি ব্যবহারকারীর ক্ষতি করে না। আপনি যদি একটি এনপ্যাপুলেটেড শ্রেণি তৈরি করেন তবে প্রতিক্রিয়াগুলি ভাল যে আপনার সমস্ত ডেটা সদস্য private
যেভাবেই হোক। আপনি সাধারণত সম্পূর্ণ এনক্যাপসুলেটেড প্রকারে পাবলিক ডেটা সদস্যদের প্রকাশ করেন না। সুতরাং এটি কেবল সেই কয়েকজন ব্যবহারকারীর জন্যই সমস্যা হবে যারা এটি করতে চান না যারা এই বিভাগটি চান।
সুতরাং এটি কোন বড় ক্ষতি।
খ) পুরো উত্তরাধিকার গাছের একমাত্র শ্রেণীর অ স্থিতিশীল ডেটা সদস্য থাকতে পারে,
এগুলির কারণ আবার ফিরে আসে কেন কেন তারা আবার মান বিন্যাসকে মানিক করে: সাধারণ অনুশীলন।
উত্তরাধিকারের গাছের দু'জন সদস্য থাকার কথা যখন আসলে জিনিস থাকে সেখানে কোনও সাধারণ অনুশীলন হয় না। কেউ অনুমানের আগে বেস ক্লাস রাখেন, অন্যরা এটি অন্য উপায়ে করেন। সদস্যরা যদি দুটি বেস ক্লাস থেকে আসে তবে আপনি কোন উপায়ে অর্ডার করবেন? ইত্যাদি। সংকলকগণ এই প্রশ্নগুলিতে ব্যাপকভাবে ডাইভারেজ করে।
এছাড়াও, শূন্য / এক / অনন্ত নিয়মের জন্য ধন্যবাদ, একবার আপনি বললে সদস্যদের সাথে আপনার দুটি ক্লাস থাকতে পারে, আপনি যতটা চান বলতে পারেন। এটি কীভাবে পরিচালনা করতে এটির জন্য প্রচুর বিন্যাসের বিধি যুক্ত করা দরকার। আপনাকে বলতে হবে যে একাধিক উত্তরাধিকার কীভাবে কাজ করে, কোন ক্লাসগুলি তাদের ডেটা অন্যান্য ক্লাসের আগে রাখে ইত্যাদি very এটি খুব সামান্য উপাদান লাভের জন্য অনেক নিয়মকানুন।
ভার্চুয়াল ফাংশন এবং একটি ডিফল্ট কনস্ট্রাক্টর স্ট্যান্ডার্ড বিন্যাস নেই এমন সমস্ত কিছুই আপনি তৈরি করতে পারবেন না।
এবং প্রথম অ-স্থিতিশীল ডেটা সদস্য বেস ক্লাসের ধরণের হতে পারে না (এটি আলিয়াসিংয়ের নিয়মগুলি ভঙ্গ করতে পারে)।
আমি সত্যিই এইটির সাথে কথা বলতে পারি না। সত্যিকার অর্থে এটি বুঝতে আমি সি ++ এর এলিয়াসিং বিধিগুলিতে যথেষ্ট শিক্ষিত নই। তবে বেস সদস্যটি বেস বর্গের মতোই ঠিকানাটি ভাগ করে নেবে এই সত্যের সাথে এর কিছু যুক্তি রয়েছে। এটাই:
struct Base {};
struct Derived : Base { Base b; };
Derived d;
static_cast<Base*>(&d) == &d.b;
এবং এটি সম্ভবত সি ++ এর এলিয়জিং নিয়মের বিপরীতে। কোনভাবে.
তবে, এটি বিবেচনা করুন: এটি আসলে করার ক্ষমতা রাখার ক্ষেত্রে কতটা কার্যকর হতে পারে? যেহেতু কেবলমাত্র একটি শ্রেণির অ স্থিতিশীল ডেটা সদস্য Derived
থাকতে পারে , তারপরে অবশ্যই সেই শ্রেণিটি হওয়া উচিত (যেহেতু এটির Base
সদস্য হিসাবে এটি রয়েছে )। সুতরাং Base
অবশ্যই খালি থাকতে হবে (ডেটা এর)। এবং যদি Base
খালি হয়, পাশাপাশি বেস ক্লাস ... কেন এটির কোনও ডেটা সদস্য আছে?
যেহেতু Base
খালি, এটির কোনও রাজ্য নেই। সুতরাং কোনও অ স্থিতিশীল সদস্য ফাংশন তারা তাদের পরামিতির উপর নির্ভর করে যা তাদের পরামিতিগুলির উপর নির্ভর করে তা করবে this
।
তাই আবার: কোনও বড় ক্ষতি।
static_cast<Base*>(&d)
এবং &d.b
একই Base*
ধরণের, তারা বিভিন্ন জিনিসকে এভাবে ভঙ্গ করে নিয়ম ভঙ্গ করে। আমাকে সংশোধন করুন
Derived
থাকতে পারে , তবে অবশ্যই সেই শ্রেণি হওয়া উচিত?
Derived
প্রথম সদস্যের বেস বেস বর্গ হওয়ার জন্য এর অবশ্যই দুটি জিনিস থাকতে হবে: একটি বেস ক্লাস এবং সদস্য । এবং যেহেতু স্তরক্রমের কেবলমাত্র একটি শ্রেণির সদস্য থাকতে পারে (এবং এখনও মানক-লেআউট হতে পারে), এর অর্থ এটির বেস শ্রেণীর সদস্য থাকতে পারে না।
সি ++ 17 আন্তর্জাতিক মানের চূড়ান্ত খসড়াটি এখানে ডাউনলোড করুন ।
দলা
সি ++ 17 সমষ্টি এবং সামগ্রিক সূচনা প্রসারণ ও বৃদ্ধি করে। স্ট্যান্ডার্ড লাইব্রেরিতে এখন একটি std::is_aggregate
টাইপ বৈশিষ্ট্য শ্রেণি অন্তর্ভুক্ত রয়েছে । এখানে ধারা ১১..6.১.১ এবং ১১..6.১.২ (আভ্যন্তরীণ রেফারেন্সগুলি যথাযথ) থেকে আনুষ্ঠানিক সংজ্ঞা দেওয়া আছে:
একটি সমষ্টি হ'ল একটি অ্যারে বা একটি শ্রেণি
- কোনও ব্যবহারকারী-সরবরাহিত, সুস্পষ্ট, বা উত্তরাধিকার সূত্রে নির্মিত নির্মাণকারী,
- কোনও ব্যক্তিগত বা সুরক্ষিত অ-স্থিতিশীল ডেটা সদস্য নয়,
- কোনও ভার্চুয়াল ফাংশন, এবং
- কোনও ভার্চুয়াল, ব্যক্তিগত বা সুরক্ষিত বেস ক্লাস নেই।
[দ্রষ্টব্য: সমষ্টিগত সূচনাটি সুরক্ষিত এবং বেসরকারী বেস শ্রেণীর সদস্য বা নির্মাতাদের অ্যাক্সেসের অনুমতি দেয় না। Noteend নোট]
একটি সামগ্রীর উপাদানগুলি হ'ল :
- একটি অ্যারের জন্য, সাবস্ক্রিপ্ট ক্রম বাড়ানোর অ্যারে উপাদানগুলি
- বা - কোন শ্রেণির জন্য, ডিক্লেয়ারেশন ক্রমে প্রত্যক্ষ বেস ক্লাসগুলি এবং তারপরে সরাসরি অ-স্থিতিশীল ডেটা সদস্য থাকে না অজ্ঞাতনামা ইউনিয়নের সদস্যগণ, ঘোষণা আদেশে।
কী বদলে গেল?
struct B1 // not a aggregate
{
int i1;
B1(int a) : i1(a) { }
};
struct B2
{
int i2;
B2() = default;
};
struct M // not an aggregate
{
int m;
M(int a) : m(a) { }
};
struct C : B1, B2
{
int j;
M m;
C() = default;
};
C c { { 1 }, { 2 }, 3, { 4 } };
cout
<< "is C aggregate?: " << (std::is_aggregate<C>::value ? 'Y' : 'N')
<< " i1: " << c.i1 << " i2: " << c.i2
<< " j: " << c.j << " m.m: " << c.m.m << endl;
//stdout: is C aggregate?: Y, i1=1 i2=2 j=3 m.m=4
struct D // not an aggregate
{
int i = 0;
D() = default;
explicit D(D const&) = default;
};
struct B1
{
int i1;
B1() : i1(0) { }
};
struct C : B1 // not an aggregate
{
using B1::B1;
};
তুচ্ছ ক্লাস
সি ++ 14 তে সম্বোধন করা হয়নি এমন বেশ কয়েকটি ত্রুটিগুলি সমাধান করার জন্য তুচ্ছ শ্রেণীর সংজ্ঞা সি ++ 17 এ পুনরায় কাজ করা হয়েছিল। পরিবর্তনগুলি প্রকৃতির ছিল প্রযুক্তিগত। এখানে 12.0.6 এ নতুন সংজ্ঞা দেওয়া হয়েছে (অভ্যন্তরীণ রেফারেন্সগুলি এলিডযুক্ত):
তুচ্ছভাবে অনুলিপিযোগ্য শ্রেণি হ'ল একটি শ্রেণি:
- যেখানে প্রতিটি কপি কন্সট্রাক্টর, মুভ কনস্ট্রাক্টর, কপি অ্যাসাইনমেন্ট অপারেটর এবং মুভ অ্যাসাইনমেন্ট অপারেটর হয় মুছে ফেলা হয় বা তুচ্ছ,
- এতে কমপক্ষে একটি মুছে ফেলা অনুলিপি করা কপির কনস্ট্রাক্টর, মুভ কনস্ট্রাক্টর, কপি অ্যাসাইনমেন্ট অপারেটর, বা অ্যাসাইনমেন্ট অপারেটর সরান, এবং
- এতে একটি তুচ্ছ, মুছে ফেলা ডেস্ট্রাক্টর নেই।
তুচ্ছ ক্লাসটি এমন একটি শ্রেণি যা তুচ্ছভাবে অনুলিপিযোগ্য এবং এতে এক বা একাধিক ডিফল্ট কনস্ট্রাক্টর থাকে যার সবগুলিই হয় তুচ্ছ বা মুছে ফেলা হয় এবং এর মধ্যে কমপক্ষে একটি মুছে ফেলা হয় না। [দ্রষ্টব্য: বিশেষত, একটি তুচ্ছভাবে অনুলিপিযোগ্য বা তুচ্ছ শ্রেণীর ভার্চুয়াল ফাংশন বা ভার্চুয়াল বেস ক্লাস নেই — শেষ নোট]
পরিবর্তন করুন:
std::memcpy
। এটি একটি শব্দার্থবিরোধ ছিল, কারণ, সমস্ত নির্মাতা / কার্যনির্বাহী অপারেটরগুলি মুছে ফেলা হিসাবে সংজ্ঞায়িত করে, শ্রেণীর স্রষ্টা স্পষ্টভাবে লক্ষ্য করেছিলেন যে ক্লাসটি অনুলিপি / সরানো যাবে না, তবুও বর্গটি তুচ্ছভাবে অনুলিপিযোগ্য শ্রেণির সংজ্ঞা পূরণ করে। সুতরাং C ++ 17 এ আমাদের একটি নতুন ধারা রয়েছে যা উল্লেখ করে যে তুচ্ছভাবে অনুলিপিযোগ্য শ্রেণীর অবশ্যই কমপক্ষে একটি তুচ্ছ, নন-মুছে ফেলা (যদিও জনসাধারণের পক্ষে অ্যাক্সেসযোগ্য নয়) কপি / মুভ কনস্ট্রাক্টর / অ্যাসাইনমেন্ট অপারেটর থাকতে হবে। দেখুন N4148 , DR1734স্ট্যান্ডার্ড-লেআউট ক্লাস
মান-বিন্যাসের সংজ্ঞাটিও ত্রুটিযুক্ত প্রতিবেদনগুলি মোকাবেলার জন্য পুনরায় কাজ করা হয়েছিল। আবার পরিবর্তনগুলি প্রকৃতির ছিল প্রযুক্তিগত। মানক (12.0.7) এর পাঠ্য এখানে। পূর্বের মত, অভ্যন্তরীণ রেফারেন্সগুলি একত্রে রয়েছে:
একটি ক্লাস এস এর একটি স্ট্যান্ডার্ড-লেআউট শ্রেণি যদি এটি থাকে:
- প্রকারের নন-স্ট্যান্ডার্ড-লেআউট শ্রেণীর (বা এই জাতীয় ধরণের অ্যারে) বা রেফারেন্সের কোনও স্থিতিশীল ডেটা সদস্য
নেই - এর কোনও ভার্চুয়াল ফাংশন এবং ভার্চুয়াল বেস শ্রেণি নেই,
- সমস্ত অ-স্থিতিশীল ডেটা সদস্যের জন্য একই অ্যাক্সেস নিয়ন্ত্রণ
রয়েছে , - কোনও মানক-বিন্যাস-বিন্যাস বেস শ্রেণি নেই,
- কোনও নির্দিষ্ট ধরণের সর্বাধিক এক বেস শ্রেণীর সাবোবজেক্ট রয়েছে, - এক্স যদি কোনও নন-ইউনিয়ন শ্রেণির ধরণ হয় যার প্রথম অ -স্ট্যাটিক ডেটা মেম্বারটির টাইপ X0 (যেখানে বলা হয়েছে সদস্য একটি বেনাম ইউনিয়ন হতে পারে), সেট এম (এক্স) এক্স0 এবং এম (এক্স0) এর উপাদানগুলি নিয়ে গঠিত। - এক্সটি যদি ইউনিয়নের ধরণ হয় তবে সেট এম (এক্স) হ'ল সমস্ত এম (ইউআই) এবং সমস্ত ইউআই সমন্বিত সেট, যেখানে প্রতিটি ইউআই এক্স এর আইথ অ-স্থিতিশীল ডেটা সদস্যের প্রকার type
- - সমস্ত অ স্থিতিশীল ডেটা সদস্য এবং বিট-ফিল্ড রয়েছে ক্লাস এবং তার বেস ক্লাসগুলি প্রথম একই শ্রেণিতে ঘোষণা করা হয়েছিল, এবং
- এর বেস এম (এস) টাইপের কোনও উপাদান নেই বেস শ্রেণি হিসাবে (নীচে সংজ্ঞায়িত) ।108
এম (এক্স) নীচে সংজ্ঞায়িত করা হয়:
- এক্সটি যদি কোনও অ-ইউনিয়ন শ্রেণীর ধরণের হয় (সম্ভবত উত্তরাধিকার সূত্রে প্রাপ্ত) অ স্থির ডেটা সদস্য নয়, সেট এম (এক্স) খালি রয়েছে। - যদি এক্স হয় এলিমেন্ট টাইপ Xe সহ একটি অ্যারে টাইপ, সেট এম (এক্স) Xe এবং এম (এক্স) এর উপাদানগুলি নিয়ে গঠিত। - এক্সটি যদি একটি শ্রেণিবদ্ধ, অ-অ্যারে প্রকার হয় তবে সেট এম (এক্স) খালি রয়েছে।
: [নোট এম (এক্স) সমস্ত অ-বেস ক্লাসের subobjects করে একটি মান-বিন্যাস ক্লাসে গ্যারান্টী আছে একটি শূন্য এক্স -end নোটে অফসেট এ হতে ধরনের সেট]
[উদাহরণ:
এর উদাহরণ]struct B { int i; }; // standard-layout class struct C : B { }; // standard-layout class struct D : C { }; // standard-layout class struct E : D { char : 4; }; // not a standard-layout class struct Q {}; struct S : Q { }; struct T : Q { }; struct U : S, T { }; // not a standard-layout class
108) এটি নিশ্চিত করে যে দুটি সাবোবজেক্টের একই শ্রেণীর ধরণ রয়েছে এবং যা একই সর্বাধিক উত্পন্ন বস্তুর অন্তর্ভুক্ত তা একই ঠিকানায় বরাদ্দ করা হয়নি।
পরিবর্তন করুন:
দ্রষ্টব্য: সি ++ স্ট্যান্ডার্ড কমিটি সি ++ 14 এ প্রয়োগ করার জন্য ত্রুটি প্রতিবেদনের উপর ভিত্তি করে উপরের পরিবর্তনগুলি লক্ষ্য করেছিল, যদিও নতুন ভাষা প্রকাশিত সি ++ 14 স্ট্যান্ডার্ডে নেই। এটি সি ++ 17 স্ট্যান্ডার্ডে রয়েছে।
এই প্রশ্নের বাকি স্পষ্ট থিম অনুসরণ করে, সামগ্রীর অর্থ এবং ব্যবহার প্রতিটি মানের সাথে অবিরত পরিবর্তন করে চলেছে। দিগন্তে বেশ কয়েকটি মূল পরিবর্তন রয়েছে।
সি ++ 17 এ, এই ধরণের এখনও একটি সমষ্টি:
struct X {
X() = delete;
};
এবং অতএব, X{}
এখনও সংকলন কারণ এটি সামগ্রিক সূচনা - কোনও নির্মাণকারীর অনুরোধ নয়। আরও দেখুন: কখন একটি বেসরকারী কনস্ট্রাক্টর বেসরকারী নির্মাণকারী নয়?
সি ++ ২০ এ, বিধিনিষেধের প্রয়োজনীয়তা থেকে পরিবর্তন হবে:
কোনও ব্যবহারকারীর দ্বারা সরবরাহিত
explicit
, বা উত্তরাধিকারসূত্রে নির্মিত নির্মাণকারী নেই
প্রতি
কোনও ব্যবহারকারী-ঘোষিত বা উত্তরাধিকারসূত্রে নির্মাণকারী নেই
এটি সি ++ ২০ কার্য খসড়াতে গৃহীত হয়েছে । আমরাও X
এখানে না C
লিঙ্ক প্রশ্নে C ++ 20 দলা হতে হবে।
এটি নিম্নলিখিত উদাহরণ সহ ইয়ো-ইও প্রভাব তৈরি করে:
class A { protected: A() { }; };
struct B : A { B() = default; };
auto x = B{};
সি ++ 11/14-এ, বেস শ্রেণীর কারণে মোট B
ছিল না , সুতরাং এটি যে অ্যাক্সেসযোগ্য সেখানে এমন এক মুহুর্তে B{}
কল করে B::B()
যা কল করে ভ্যালু-ইনিশিলাইজেশন সম্পাদন করে A::A()
। এটি সুসংহত ছিল।
সি ++ 17 এ, B
সমষ্টিগত হয়ে ওঠে কারণ বেস ক্লাসগুলির অনুমতি ছিল, যা B{}
সামগ্রিক-সূচনা করেছিল। এই কপি-তালিকা-আরম্ভ করার সময় একটি প্রয়োজন A
থেকে {}
, কিন্তু থেকে প্রেক্ষাপটে বাহিরে B
, যেখানে এটি অ্যাক্সেসযোগ্য নয়। সি ++ 17-এ, এটি খারাপ-গঠন ( auto x = B();
যদিও ভাল হবে)।
সি ++ তে এখন, উপরোক্ত নিয়ম পরিবর্তনের কারণে, B
আবারও একটি সমষ্টি হতে হবে (বেস শ্রেণীর কারণে নয়, তবে ব্যবহারকারী-ঘোষিত ডিফল্ট কনস্ট্রাক্টরের কারণে - যদিও এটি খেলাপি হয়েছে)। সুতরাং আমরা আবার B
'কনস্ট্রাক্টর'-এর মধ্য দিয়ে যাচ্ছি এবং এই স্নিপেটটি সু-গঠনযুক্ত।
একটি সাধারণ সমস্যা যা আসে তা হ'ল emplace()
সমষ্টি সহ স্টাইল নির্মাণকারী ব্যবহার করতে :
struct X { int a, b; };
std::vector<X> xs;
xs.emplace_back(1, 2); // error
এটি কার্যকর হয় না, কারণ emplace
কার্যকরভাবে প্রাথমিকভাবে সঞ্চালনের চেষ্টা করবে X(1, 2)
যা বৈধ নয়। সাধারণ সমাধানটি হ'ল একজন কনস্ট্রাক্টর যুক্ত করা X
, তবে এই প্রস্তাবের (বর্তমানে কোরের মধ্য দিয়ে তার কাজ চলছে) সমষ্টিগুলিতে কার্যকরভাবে সংশ্লেষিত কনস্ট্রাক্টর থাকবে যা সঠিক কাজ করে - এবং নিয়মিত নির্মাণকারীর মতো আচরণ করবে। উপরের কোডটি সি ++ ২০ তে সংকলন করবে।
সি ++ 17 এ এটি সংকলন করে না:
template <typename T>
struct Point {
T x, y;
};
Point p{1, 2}; // error
সমস্ত সামগ্রিক টেম্পলেটগুলির জন্য তাদের নিজস্ব ছাড়ের গাইড লিখতে হবে:
template <typename T> Point(T, T) -> Point<T>;
তবে যেহেতু এটি কিছুটা অর্থে "সুস্পষ্ট জিনিস" এবং মূলত কেবল বয়লারপ্লেট হিসাবে রয়েছে, ভাষাটি আপনার জন্য এটি করবে। এই উদাহরণটি সি ++ ২০ (ব্যবহারকারী দ্বারা সরবরাহিত ছাড়ের গাইডের প্রয়োজন ছাড়াই) সংকলন করবে।