অভ্যন্তরীণভাবে এবং উত্পন্ন কোড সম্পর্কে, এর মধ্যে কি সত্যিই পার্থক্য রয়েছে:
MyClass::MyClass(): _capacity(15), _data(NULL), _len(0)
{
}
এবং
MyClass::MyClass()
{
_capacity=15;
_data=NULL;
_len=0
}
ধন্যবাদ ...
উত্তর:
ধরে নিচ্ছি যে এই মানগুলি আদিম ধরণের, তবে না, কোনও পার্থক্য নেই। সূচনা তালিকাগুলি কেবল তখনই পার্থক্য তৈরি করে যখন আপনার সদস্য হিসাবে অবজেক্ট থাকে, যেহেতু অ্যাসাইনমেন্ট অনুসারে ডিফল্ট ইনিশিয়ালেশন ব্যবহার না করে, সূচনা তালিকা আপনাকে তার চূড়ান্ত মানটিতে অবজেক্টটি আরম্ভ করতে দেয়। এটি আসলে লক্ষণীয়ভাবে দ্রুত হতে পারে।
ধ্রুবক সদস্য, রেফারেন্স এবং বেস ক্লাস আরম্ভ করার জন্য আপনার সূচনা তালিকাটি ব্যবহার করতে হবে
যখন আপনাকে ধ্রুবক সদস্য, রেফারেন্স এবং বেস ক্লাস কনস্ট্রাক্টরগুলিকে পরামিতিগুলি পাস করার দরকার হয়, যেমন মন্তব্যগুলিতে উল্লিখিত হয়েছে, আপনাকে আরম্ভের তালিকাটি ব্যবহার করতে হবে।
struct aa
{
int i;
const int ci; // constant member
aa() : i(0) {} // will fail, constant member not initialized
};
struct aa
{
int i;
const int ci;
aa() : i(0) { ci = 3;} // will fail, ci is constant
};
struct aa
{
int i;
const int ci;
aa() : i(0), ci(3) {} // works
};
উদাহরণ (সম্পূর্ণ নয়) শ্রেণি / কাঠামোর উল্লেখ রয়েছে:
struct bb {};
struct aa
{
bb& rb;
aa(bb& b ) : rb(b) {}
};
// usage:
bb b;
aa a(b);
এবং বেস শ্রেণীর সূচনা করার উদাহরণ যার জন্য প্যারামিটার প্রয়োজন (উদাহরণস্বরূপ কোনও ডিফল্ট নির্মাণকারী নেই):
struct bb {};
struct dd
{
char c;
dd(char x) : c(x) {}
};
struct aa : dd
{
bb& rb;
aa(bb& b ) : dd('a'), rb(b) {}
};
_capacity
, _data
এবং _len
অ্যাক্সেসযোগ্য ডিফল্ট নির্মাণকারী ছাড়া ক্লাসের ধরণ রয়েছে?
const
কন্সট্রাক্টরের শরীরে সদস্যকে আরম্ভ করতে পারবেন না , আপনাকে আরম্ভের তালিকাটি ব্যবহার const
করতে হবে - অ- সদস্যদের সূচনা তালিকায় বা কনস্ট্রাক্টরের মূল অংশে আরম্ভ করা যেতে পারে।
হ্যাঁ. প্রথম যদি আপনি ডিক্লেয়ার করতে পারেন _capacity
, _data
এবং _len
ধ্রুবক হিসাবে:
class MyClass
{
private:
const int _capacity;
const void *_data;
const int _len;
// ...
};
এটি গুরুত্বপূর্ণ হবে যদি আপনি const
রানটাইমের সময় এই উদাহরণগুলির পরিবর্তনশীলগুলির মানগুলি গণনা করার সময় নিশ্চিত করতে চান , উদাহরণস্বরূপ:
MyClass::MyClass() :
_capacity(someMethod()),
_data(someOtherMethod()),
_len(yetAnotherMethod())
{
}
const
দৃষ্টান্তগুলি অবশ্যই আরম্ভকারী তালিকায় শুরু করতে হবে বা অন্তর্নিহিত প্রকারগুলি অবশ্যই সর্বজনীন পরামিতি বিহীন নির্মাতাদের সরবরাহ করতে হবে (যা আদিম ধরণেরগুলি করে)।
আমি মনে করি এই লিঙ্কটি http://www.cplusplus.com/forum/articles/17820/ একটি দুর্দান্ত ব্যাখ্যা দেয় - বিশেষত সি ++ তে নতুন যারা।
অন্তর্বর্তী তালিকার তালিকা আরও দক্ষ হওয়ার কারণটি হল কনস্ট্রাক্টর বডির মধ্যে কেবলমাত্র অ্যাসাইনমেন্ট হয়, আরম্ভ হয় না। সুতরাং আপনি যদি একটি অন্তর্নির্মিত প্রকারের সাথে ডিল করছেন, তবে কনস্ট্রাক্টরের শরীরে প্রবেশের আগে that অবজেক্টের জন্য ডিফল্ট কনস্ট্রাক্টরকে ইতিমধ্যে ডেকে আনা হয়েছে। কনস্ট্রাক্টর বডির ভিতরে আপনি সেই অবজেক্টের জন্য একটি মান নির্ধারণ করছেন।
কার্যত, এটি ডিফল্ট কনস্ট্রাক্টরের একটি কল এবং তারপরে অনুলিপি-অ্যাসাইনমেন্ট অপারেটরের কাছে কল। প্রারম্ভিক তালিকাটি আপনাকে সরাসরি অনুলিপি কন্সট্রাক্টরকে কল করতে দেয় এবং এটি মাঝে মাঝে উল্লেখযোগ্যভাবে দ্রুত হতে পারে (মনে রাখবেন যে আরম্ভকারী তালিকাটি কনস্ট্রাক্টরের দেহের আগে রয়েছে)
আমি যুক্ত করব যে আপনার যদি ক্লাস ধরণের সদস্য নেই তবে কোনও ডিফল্ট কনস্ট্রাক্টর উপলব্ধ নেই, আপনার ক্লাসটি তৈরির একমাত্র উপায় ইনিশিয়ালাইজেশন।
একটি বড় পার্থক্য হ'ল এই নিয়োগটি পিতামাতার শ্রেণীর সদস্যদের সূচনা করতে পারে; ইনিশিয়ালাইজার কেবলমাত্র বর্তমান শ্রেণীর স্কোপে ঘোষিত সদস্যদের উপর কাজ করে।
আসল পার্থক্যটি কীভাবে জিসিসি সংকলক মেশিন কোড জেনারেট করে এবং মেমরিটি রাখে তা নিয়ে ফোটে। ব্যাখ্যা করা:
কনস্টের ধরণের সদস্যদের পরিচালনা করার অবশ্যই অন্যান্য উপায় রয়েছে। তবে তাদের জীবনকে স্বাচ্ছন্দ্য করতে, জিসিসি সংকলক লেখকরা কিছু বিধি সেট আপ করার সিদ্ধান্ত নেন
আরম্ভ করার একমাত্র উপায় আছেবেস শ্রেণীর উদাহরণগুলি এবং অ-স্থিতিশীল সদস্য ভেরিয়েবলগুলি এবং তা হ'ল আরম্ভকারী তালিকাটি ব্যবহার করা।
আপনি যদি আপনার নির্মাণকারীর প্রাথমিক তালিকায় কোনও বেস বা অ-স্থিতিশীল সদস্যের পরিবর্তনশীল নির্দিষ্ট না করে থাকেন তবে সেই সদস্য বা বেসটি ডিফল্ট-আরম্ভ হবে (সদস্য / বেস যদি নন-পিওড শ্রেণীর ধরণ বা নন-পিওডি শ্রেণীর অ্যারে হয় তবে প্রকারভেদ) বা অন্যথায় অবিচ্ছিন্ন বাম।
কনস্ট্রাক্টর বডিতে প্রবেশ করার পরে, সমস্ত ঘাঁটি বা সদস্যদের ইনিশিয়াল করা বা অবিরামিত রেখে দেওয়া হবে (অর্থাত তাদের একটি অনির্দিষ্ট মান থাকবে)। তাদের কীভাবে প্রাথমিককরণ করা উচিত তা প্রভাবিত করার জন্য কনস্ট্রাক্টর বডিতে কোনও সুযোগ নেই।
আপনি কনস্ট্রাক্টর বডিতে সদস্যদের জন্য নতুন মান নির্ধারণ করতে সক্ষম হতে পারেন তবে এটি নির্ধারণ করা সম্ভব নয় is const
সদস্যদের বা অ- হয়েছে এবং রেফারেন্সগুলি পুনরায় প্রত্যাবর্তন করা সম্ভব নয় এমন শ্রেণীর সদস্য বা সদস্যদের সম্ভব নয়।
প্রকারভেদে নির্মিত এবং কিছু ব্যবহারকারী-সংজ্ঞায়িত প্রকারের জন্য, কনস্ট্রাক্টর বডিতে নির্ধারণের ক্ষেত্রে ইনিশিয়ালার তালিকার একই মান দিয়ে আরম্ভ করার মতো একই প্রভাব থাকতে পারে।
আপনি যদি কোনও প্রাথমিক বা তালিকার কোনও সদস্য বা বেসের নাম দিতে ব্যর্থ হন এবং সেই সত্তাটি একটি রেফারেন্স হয়, কোনও ক্লাসের ধরণ নেই যার দ্বারা অ্যাক্সেসযোগ্য ব্যবহারকারী-ঘোষিত ডিফল্ট কনস্ট্রাক্টর নেই, const
যোগ্য এবং পিওড টাইপ বা পিওড শ্রেণির ধরণ বা পিওড শ্রেণির ধরণের অ্যারে একজন const
যোগ্যতাসম্পন্ন সদস্য সমন্বিত (প্রত্যক্ষ বা পরোক্ষভাবে) এর পরে প্রোগ্রামটি দুর্গঠিত।
আপনি যদি একটি প্রাথমিক তালিকার তালিকা লিখেন, আপনি সমস্ত এক ধাপে করেন; আপনি যদি কোনও ইনিমিলাইজার তালিকাটি না লিখে থাকেন তবে আপনি 2 টি পদক্ষেপ করবেন: একটি ঘোষণার জন্য এবং একটিতে মানটি স্বাক্ষর করার জন্য।
কনস্ট্রাক্টরে ইনিশিয়ালাইজেশন তালিকা এবং ইনিশিয়ালাইজেশন স্টেটমেন্টের মধ্যে পার্থক্য রয়েছে। কোড নীচে বিবেচনা করা যাক:
#include <initializer_list>
#include <iostream>
#include <algorithm>
#include <numeric>
class MyBase {
public:
MyBase() {
std::cout << __FUNCTION__ << std::endl;
}
};
class MyClass : public MyBase {
public:
MyClass::MyClass() : _capacity( 15 ), _data( NULL ), _len( 0 ) {
std::cout << __FUNCTION__ << std::endl;
}
private:
int _capacity;
int* _data;
int _len;
};
class MyClass2 : public MyBase {
public:
MyClass2::MyClass2() {
std::cout << __FUNCTION__ << std::endl;
_capacity = 15;
_data = NULL;
_len = 0;
}
private:
int _capacity;
int* _data;
int _len;
};
int main() {
MyClass c;
MyClass2 d;
return 0;
}
যখন মাইক্লাস ব্যবহার করা হবে তখন নির্বাহকের প্রথম বিবৃতি কার্যকর করার আগে সমস্ত সদস্যকে আরম্ভ করা হবে।
কিন্তু, যখন মাইক্লাস 2 ব্যবহার করা হয়, যখন কোনও কনস্ট্রাক্টরের প্রথম বিবৃতি কার্যকর করা হয় তখন সমস্ত সদস্য আরম্ভ হয় না।
পরে ক্ষেত্রে, নির্দিষ্ট সদস্যের সূচনা করার আগে কেউ যদি কোনও কনস্ট্রাক্টরে কিছু কোড যুক্ত করে তখন রিগ্রেশন সমস্যা হতে পারে।
এখানে এমন একটি বিষয় যা আমি অন্যকে এটি উল্লেখ করতে দেখিনি:
class temp{
public:
temp(int var);
};
টেম্প ক্লাসে একটি ডিফল্ট কর্টর নেই। যখন আমরা এটি অন্য শ্রেণিতে নিম্নলিখিত হিসাবে ব্যবহার করি:
class mainClass{
public:
mainClass(){}
private:
int a;
temp obj;
};
কোডটি সংকলন করবে না, কারণ obj
সংকলকটি কীভাবে আরম্ভ করতে হবে তা জানে না , কারণ এটির মধ্যে কেবল একটি স্পষ্ট স্পষ্ট বর্ণ রয়েছে যা কোনও মান অর্জন করে, সুতরাং আমাদের নিম্নলিখিত হিসাবে নিম্নলিখিতটি পরিবর্তন করতে হবে:
mainClass(int sth):obj(sth){}
সুতরাং, এটি কেবল কনস্ট এবং রেফারেন্সগুলিই নয়!