প্রশ্নাবলীর "লুকানো বৈশিষ্ট্যগুলি" কী আসে যায় না? ভেবেছিলাম আমি ওখানে ফেলে দেব। সি ++ এর কিছু লুকানো বৈশিষ্ট্য কী কী?
প্রশ্নাবলীর "লুকানো বৈশিষ্ট্যগুলি" কী আসে যায় না? ভেবেছিলাম আমি ওখানে ফেলে দেব। সি ++ এর কিছু লুকানো বৈশিষ্ট্য কী কী?
উত্তর:
বেশিরভাগ সি ++ প্রোগ্রামারগুলি টের্নারি অপারেটরের সাথে পরিচিত:
x = (y < 0) ? 10 : 20;
তবে, তারা বুঝতে পারে না যে এটি একটি মূল্য হিসাবে ব্যবহার করা যেতে পারে:
(a == 0 ? a : b) = 1;
যা সংক্ষিপ্ত
if (a == 0)
a = 1;
else
b = 1;
সতর্কতার সাথে ব্যবহার করুন :-)
(value ? function1 : function2)()
।
function1
এবং function2
জড়িতভাবে ফাংশন পয়েন্টারে রূপান্তরিত হয় এবং ফলাফলটি স্পষ্টতই ফিরে রূপান্তরিত হয়।
আপনি ত্রুটি ছাড়াই সি ++ উত্সে ইউআরআই রাখতে পারেন। উদাহরণ স্বরূপ:
void foo() {
http://stackoverflow.com/
int bar = 4;
...
}
goto
, যা সি ++ থাকে)। দুটি টুকরো টুকরো করে নিম্নলিখিত যে কোনও কিছু মন্তব্য thing অতএব, এর সাথে http://stackoverflow.com
, http
একটি লেবেল (আপনি তাত্ত্বিকভাবে লিখতে পারেন goto http;
), এবং //stackoverflow.com
এটি কেবল একটি শেষ-লাইন মন্তব্য। এগুলি উভয়ই আইনী সি ++, তাই সংকলনগুলি তৈরি করুন। এটি অবশ্যই অস্পষ্টভাবে কার্যকর কিছু করে না।
goto http;
আসলে URL টি অনুসরণ করে না। :(
পয়েন্টার গাণিতিক।
সি ++ প্রোগ্রামাররা যে বাগগুলি প্রবর্তন করা যেতে পারে তার কারণে পয়েন্টার এড়াতে পছন্দ করে।
দুর্দান্ত সি ++ আমি কি কখনও দেখেছি? অ্যানালগ আক্ষরিক।
আমি সেখানে বেশিরভাগ পোস্টের সাথে একমত: সি ++ একটি বহু-দৃষ্টিকোণ ভাষা, সুতরাং যে "গোপন" বৈশিষ্ট্যগুলি আপনি পাবেন ("অপরিজ্ঞাত আচরণগুলি" ব্যতীত যা আপনার কোনও মূল্যে এড়ানো উচিত) হ'ল সুবিধার সুবিধাযুক্ত ব্যবহার।
এই সুবিধাগুলিগুলির বেশিরভাগ ভাষাটির বিল্ট-ইন বৈশিষ্ট্যগুলি নয়, তবে গ্রন্থাগার-ভিত্তিক।
সর্বাধিক গুরুত্বপূর্ণ হ'ল RAII , প্রায়শই কয়েক বছর ধরে সি ++ বিকাশকারীদের দ্বারা সি বিশ্ব থেকে আগত। অপারেটর ওভারলোডিং প্রায়শই একটি ভুল বোঝাবুঝি বৈশিষ্ট্য যা উভয় অ্যারে-জাতীয় আচরণ (সাবস্ক্রিপ্ট অপারেটর), পয়েন্টারের মতো অপারেশন (স্মার্ট পয়েন্টার) এবং বিল্ড-ইন-লাইক ক্রিয়াকলাপগুলি (বহুগুণিত ম্যাট্রিক্স) সক্ষম করে।
ব্যতিক্রমের ব্যবহার প্রায়শই কঠিন, তবে কিছু কাজ করে, ব্যতিক্রমী সুরক্ষা বৈশিষ্ট্যের মাধ্যমে সত্যিকারের শক্ত কোড তৈরি করতে পারে (কোড সহ যা ব্যর্থ হবে না, বা এতে কমিটের মতো বৈশিষ্ট্য রয়েছে যা সফল হবে, বা ফিরে ফিরে যাবে) এর মূল অবস্থা)।
সি ++ এর সর্বাধিক বিখ্যাত "লুকানো" বৈশিষ্ট্যটি হ'ল টেমপ্লেট বিপণন , কারণ এটি আপনাকে রানটাইমের পরিবর্তে সংকলন সময়ে আপনার প্রোগ্রামটি আংশিক (বা সম্পূর্ণ) সম্পাদন করতে সক্ষম করে। এটি যদিও এটি কঠিন, এবং এটির চেষ্টা করার আগে আপনার অবশ্যই টেমপ্লেটগুলিতে একটি দৃ gra় দখল থাকা উচিত।
অন্যান্য সি ++ এর পূর্বপুরুষের বাইরে, অর্থাৎ সি এর বাইরে "প্রোগ্রামিংয়ের পদ্ধতি" তৈরি করতে একাধিক দৃষ্টান্ত ব্যবহার করে make
ফান্টেক্টর ব্যবহার করে , আপনি অতিরিক্ত টাইপ-সুরক্ষা এবং রাষ্ট্রীয় হওয়ার সাথে সাথে ফাংশনগুলি অনুকরণ করতে পারেন। কমান্ড প্যাটার্ন ব্যবহার করে আপনি কোড প্রয়োগে বিলম্ব করতে পারেন। "অফিসিয়াল সি ++ অনুচ্ছেদের" তালিকার ভিতরে থাকা বিকল্প কোডিং শৈলীগুলি তৈরি করার জন্য সর্বাধিক অন্যান্য নকশার নিদর্শনগুলি সি এবং+ এ সহজে এবং দক্ষতার সাথে প্রয়োগ করা যেতে পারে।
টেমপ্লেটগুলি ব্যবহার করে আপনি এমন কোড তৈরি করতে পারেন যা বেশিরভাগ ধরণের ক্ষেত্রে কাজ করবে, আপনি প্রথমে ভেবেছিলেন এমনটি নয়। আপনি প্রকারের সুরক্ষাও বাড়িয়ে তুলতে পারেন (যেমন একটি স্বয়ংক্রিয় টাইপসেফ ম্যালোক / রিলোক / ফ্রি)। সি ++ অবজেক্ট বৈশিষ্ট্যগুলি সত্যই শক্তিশালী (এবং এইভাবে, যদি অযত্নে ব্যবহার করা হয় তবে বিপজ্জনক), তবে এমনকি গতিশীল পলিমারফিজমের সি ++ তে স্থির সংস্করণ রয়েছে: সিআরটিপি ।
আমি খুঁজে পেয়েছি যে স্কট মায়ার্সের বেশিরভাগ " কার্যকর সি ++ " - টাইপ বইগুলি বা " ব্যতিক্রমী সি ++ " - হার্ব সটারের টাইপ বইগুলি উভয়ই পড়া সহজ, এবং সি ++ এর জ্ঞাত এবং কম পরিচিত বৈশিষ্ট্যগুলির তথ্যের বেশিরভাগ ধনকোষ।
আমার পছন্দের মধ্যে একটি হ'ল যে কোনও জাভা প্রোগ্রামারের চুলকে ভয়ঙ্কর থেকে উত্থিত করা উচিত: সি ++ এ, কোনও অবজেক্টে কোনও বৈশিষ্ট্য যুক্ত করার সর্বাধিক অবজেক্ট-ওরিয়েন্টেড উপায় হ'ল সদস্যের পরিবর্তে অ-সদস্যবিহীন বন্ধু-বান্ধব ক্রিয়াকলাপের মাধ্যমে- ফাংশন (অর্থাত ক্লাস পদ্ধতি), কারণ:
সি ++ তে, একটি শ্রেণি ইন্টারফেস তার সদস্য-কার্য এবং একই নেমস্পেসে অ-সদস্য ফাংশন উভয়ই
অ-বন্ধুহীন অ-সদস্যের কার্যক্রমে অভ্যন্তরীণ শ্রেণিতে কোনও সুযোগ সুবিধা নেই to এর মতো, অ-সদস্যের অ-বন্ধুর উপরে সদস্য ফাংশন ব্যবহার করা ক্লাসের 'এনপ্যাপসুলেশনকে দুর্বল করে দেয়।
এটি অভিজ্ঞ বিকাশকারীদেরও অবাক করে না।
(উত্স: অন্যদের মধ্যে, ভেষজ সুটারের সপ্তাহের অনলাইন গুরু # 84: http://www.gotw.ca/gotw/084.htm )
একটি ভাষার বৈশিষ্ট্য যা আমি কিছুটা গোপন বলে মনে করি, কারণ আমি স্কুলে আমার পুরো সময় জুড়ে এর আগে কখনও শুনিনি, এটি হ'ল নেমস্পেসের নাম। বুস্ট ডকুমেন্টেশনে এর উদাহরণগুলিতে না যাওয়া পর্যন্ত এটি আমার নজরে আনা হয়নি। অবশ্যই, এখন যেহেতু আমি এটি সম্পর্কে জানি আপনি এটি যে কোনও মানক সি ++ রেফারেন্সে খুঁজে পেতে পারেন।
namespace fs = boost::filesystem;
fs::path myPath( strPath, fs::native );
using
।
একটি for
লুপের init অংশে কেবল ভেরিয়েবলগুলিই ঘোষিত হতে পারে না , তবে শ্রেণি এবং ক্রিয়াকলাপগুলিও।
for(struct { int a; float b; } loop = { 1, 2 }; ...; ...) {
...
}
এটি বিভিন্ন ধরণের একাধিক ভেরিয়েবলের অনুমতি দেয়।
অ্যারে অপারেটরটি সহযোগী।
এ [8] হ'ল * (এ + 8) এর প্রতিশব্দ। যেহেতু সংযোজনমূলক, তাই এটি * (8 + এ) হিসাবে আবারও লেখা যেতে পারে, যা ..... 8 [এ] এর প্রতিশব্দ
আপনি দরকারী বলেছেন না ... :-)
A
এ সব কোন ব্যাপার না। উদাহরণস্বরূপ, যদি A
এটি হয় char*
তবে কোডটি এখনও বৈধ হবে।
একটি জিনিস যা খুব কম জানা যায় তা হ'ল ইউনিয়নগুলিও টেম্পলেট হতে পারে:
template<typename From, typename To>
union union_cast {
From from;
To to;
union_cast(From from)
:from(from) { }
To getTo() const { return to; }
};
এবং তারা কনস্ট্রাক্টর এবং সদস্য ফাংশনও থাকতে পারে। উত্তরাধিকারের সাথে কেবল কিছুই করার নেই (ভার্চুয়াল ফাংশন সহ)।
From
এবং To
সেট এবং ব্যবহার করা হয় সেই অনুযায়ী। এই জাতীয় ইউনিয়ন সংজ্ঞায়িত আচরণের সাথে ব্যবহার করা যেতে পারে যদিও ( To
স্বাক্ষরযুক্ত চরের অ্যারে হওয়া বা কোনও কাঠামোর সাথে প্রাথমিক ক্রম ভাগ করে নেওয়া From
)। এমনকি আপনি এটি অপরিজ্ঞাত উপায়ে ব্যবহার করলেও এটি নিম্ন-স্তরের কাজের জন্য কার্যকর হতে পারে। যাইহোক, এটি ইউনিয়নের টেমপ্লেটের কেবল একটি উদাহরণ - একটি টেম্প্লেটেড ইউনিয়নের জন্য অন্যান্য ব্যবহার থাকতে পারে।
সি ++ একটি মান, এখানে কোনও লুকানো বৈশিষ্ট্য থাকা উচিত নয় ...
সি ++ হ'ল এক বহুমাত্রিক ভাষা, আপনি লুকানো বৈশিষ্ট্য থাকার কারণে আপনার শেষ অর্থের উপর বাজি রাখতে পারেন। অনেকের মধ্যে একটি উদাহরণ: টেমপ্লেট metaprogramming । স্ট্যান্ডার্ড কমিটির কেউই সেখানে কোনও টুরিং-সম্পূর্ণ সাবল্যাংগ্যায়েজ করার ইচ্ছা করেনি যা সংকলন সময়ে কার্যকর করা হয়েছিল।
আর একটি লুকানো বৈশিষ্ট্য যা সি তে কাজ করে না তা হ'ল ইউনিারি +
অপারেটরের কার্যকারিতা । আপনি এটিকে সমস্ত ধরণের জিনিস প্রচার এবং ক্ষয় করতে ব্যবহার করতে পারেন
+AnEnumeratorValue
এবং আপনার গণকের মান যা আগে এর গণনা টাইপ ছিল এখন সঠিক পূর্ণসংখ্যার টাইপ রয়েছে যা এর মানটি ফিট করতে পারে। ম্যানুয়ালি, আপনি খুব সহজেই এই ধরণের জানতেন! উদাহরণস্বরূপ এটি প্রয়োজন যখন আপনি নিজের গণনার জন্য একটি ওভারলোডেড অপারেটরটি প্রয়োগ করতে চান।
আপনাকে এমন একটি ক্লাস ব্যবহার করতে হবে যা ক্লাস সংজ্ঞা ছাড়াই একটি শ্রেণির স্ট্যাটিক ইনিশিয়ালাইজার ব্যবহার করে তবে কখনও কখনও এটি লিঙ্ক করতে ব্যর্থ হয়? অপারেটর তার ধরণের উপর নির্ভরযোগ্যতা বা নির্ভরতা না তৈরি করে একটি অস্থায়ী তৈরি করতে সহায়তা করতে পারে
struct Foo {
static int const value = 42;
};
// This does something interesting...
template<typename T>
void f(T const&);
int main() {
// fails to link - tries to get the address of "Foo::value"!
f(Foo::value);
// works - pass a temporary value
f(+Foo::value);
}
আপনি কি কোনও ফাংশনে দুটি পয়েন্টার পাস করতে চান তবে এটি কার্যকর হবে না? অপারেটর সাহায্য করতে পারে
// This does something interesting...
template<typename T>
void f(T const& a, T const& b);
int main() {
int a[2];
int b[3];
f(a, b); // won't work! different values for "T"!
f(+a, +b); // works! T is "int*" both time
}
রেফারেন্সগুলিতে আবদ্ধ অস্থায়ীদের জীবনকাল এমন একটি যা খুব কম লোকই জানেন know বা কমপক্ষে এটি আমার প্রিয় সি ++ জ্ঞানের টুকরো যা বেশিরভাগ লোকেরা জানেন না।
const MyClass& x = MyClass(); // temporary exists as long as x is in scope
একটি দুর্দান্ত বৈশিষ্ট্য যা প্রায়শই ব্যবহৃত হয় না তা হ'ল ফাংশন-ওয়াইড ট্রাই-ক্যাচ ব্লক:
int Function()
try
{
// do something here
return 42;
}
catch(...)
{
return -1;
}
প্রধান ব্যবহার হ'ল ব্যতিক্রমগুলি অন্য ব্যতিক্রম শ্রেণি এবং পুনর্বিবেচনার ব্যতিক্রম অনুবাদ করা বা ব্যতিক্রম এবং রিটার্ন-ভিত্তিক ত্রুটি কোড হ্যান্ডলিংয়ের মধ্যে অনুবাদ করা।
return
ফাংশন ট্রাই ধরার ব্লক থেকে কেবল পুনর্নবীকরণ করতে পারেন।
অনেকে identity
/ id
রূপান্তরটি জানেন , তবে এটি টেম্পলেট-না-করা মামলার জন্য একটি দুর্দান্ত ব্যবহারের ঘড়ি রয়েছে: সহজেই লেখার ঘোষণা:
// void (*f)(); // same
id<void()>::type *f;
// void (*f(void(*p)()))(int); // same
id<void(int)>::type *f(id<void()>::type *p);
// int (*p)[2] = new int[10][2]; // same
id<int[2]>::type *p = new int[10][2];
// void (C::*p)(int) = 0; // same
id<void(int)>::type C::*p = 0;
এটি সি ++ ডিক্লোরেশনগুলি ব্যাপকভাবে ডিক্রিপ্টিংয়ে সহায়তা করে!
// boost::identity is pretty much the same
template<typename T>
struct id { typedef T type; };
template<typename Ret,typename... Args> using function = Ret (Args...); template<typename T> using pointer = *T;
-> pointer<function<void,int>> f(pointer<function<void,void>>);
বা pointer<void(int)> f(pointer<void()>);
বাfunction<pointer<function<void,int>>,pointer<function<void,void>>> f;
একটি গোপন বৈশিষ্ট্য হ'ল আপনি যদি একটি শর্তের মধ্যে ভেরিয়েবল সংজ্ঞায়িত করতে পারেন এবং এর ব্যাপ্তি কেবলমাত্র if এবং এর অন্য ব্লকগুলিতে বিস্তৃত হবে:
if(int * p = getPointer()) {
// do something
}
কিছু ম্যাক্রো এটি ব্যবহার করে, উদাহরণস্বরূপ কিছু "লকড" স্কোপ সরবরাহ করার জন্য:
struct MutexLocker {
MutexLocker(Mutex&);
~MutexLocker();
operator bool() const { return false; }
private:
Mutex &m;
};
#define locked(mutex) if(MutexLocker const& lock = MutexLocker(mutex)) {} else
void someCriticalPath() {
locked(myLocker) { /* ... */ }
}
এছাড়াও BOOST_FOREach হুডের নীচে এটি ব্যবহার করে। এটি সম্পূর্ণ করার জন্য, এটি কেবলমাত্র একটি ক্ষেত্রেই সম্ভব নয়, একটি স্যুইচও সম্ভব:
switch(int value = getIt()) {
// ...
}
এবং কিছুক্ষণের মধ্যে লুপ:
while(SomeThing t = getSomeThing()) {
// ...
}
(এবং শর্তের জন্যও) তবে আমি খুব বেশি নিশ্চিত নই যে এগুলি সমস্ত কার্যকর কিনা :)
if((a = f()) == b) ...
তবে এই উত্তরটি আসলে শর্তে পরিবর্তনশীল হিসাবে ঘোষণা করে।
for(...; int i = foo(); ) ...;
এটি যতক্ষণ i
সত্য হয় ততক্ষণে এটি প্রতিবারই শুরু করে দেহের মধ্যে দিয়ে যাবে । আপনি যে লুপটি দেখান তা কেবল একটি পরিবর্তনীয় ঘোষণা প্রদর্শন করে তবে পরিবর্তনশীল ঘোষণা নয় যা একযোগে শর্ত হিসাবে কাজ করে :)
কখনও কখনও আপনি কমা অপারেটরটির বৈধ ব্যবহার করেন তবে আপনি এটি নিশ্চিত করতে চান যে কোনও ব্যবহারকারী সংজ্ঞায়িত কমা অপারেটর পথে না চলে, কারণ উদাহরণস্বরূপ আপনি বাম এবং ডান পাশের সিকোয়েন্স পয়েন্টগুলিতে নির্ভর করেন বা নিশ্চিত হন যে কোনও কিছুই কাঙ্ক্ষিত ক্ষেত্রে হস্তক্ষেপ করছে না। কর্ম. এখানেই void()
খেলায় আসে:
for(T i, j; can_continue(i, j); ++i, void(), ++j)
do_code(i, j);
শর্ত এবং কোডের জন্য আমি যে স্থানধারীদের রেখেছি তা উপেক্ষা করুন। সবচেয়ে গুরুত্বপূর্ণটি হ'ল void()
, যা অন্তর্নির্মিত কমা অপারেটরটি ব্যবহার করতে সংকলককে বাধ্য করে। বৈশিষ্ট্য ক্লাসগুলি প্রয়োগ করার সময় এটি কখনও কখনও কার্যকর হতে পারে।
কনস্ট্রাক্টরে অ্যারে ইনিশিয়ালাইজেশন। উদাহরণস্বরূপ কোনও শ্রেণিতে যদি আমাদের মতো একটি অ্যারে থাকে int
:
class clName
{
clName();
int a[10];
};
কনস্ট্রাক্টরে আমরা অ্যারের সমস্ত উপাদান এর ডিফল্ট (এখানে অ্যারের সমস্ত উপাদান শূন্যে) হিসাবে শুরু করতে পারি:
clName::clName() : a()
{
}
ওহ, আমি পরিবর্তে পোষা ঘৃণ্য একটি তালিকা নিয়ে আসতে পারি:
প্লাস পাশ দিয়ে
আপনি অনির্ধারিত আচরণ ছাড়াই এবং প্রত্যাশিত শব্দার্থকতা সহ সুরক্ষিত ডেটা এবং কোনও শ্রেণীর ফাংশন সদস্য অ্যাক্সেস করতে পারেন। কিভাবে দেখুন পড়ুন। এই সম্পর্কে ত্রুটি প্রতিবেদনটি পড়ুন ।
সাধারণত, সি ++ আপনাকে শ্রেণীর অবজেক্টের অ স্থিতিশীল সুরক্ষিত সদস্যদের অ্যাক্সেস করতে নিষেধ করে, এমনকি সেই শ্রেণিটি যদি আপনার বেস শ্রেণি হয়
struct A {
protected:
int a;
};
struct B : A {
// error: can't access protected member
static int get(A &x) { return x.a; }
};
struct C : A { };
এটি নিষিদ্ধ: আপনি এবং সংকলক জানেন না যে রেফারেন্সটি আসলে কী নির্দেশ করে। এটি কোনও C
অবজেক্ট হতে পারে , যেখানে শ্রেণীর B
কোনও ডেটা বা ব্যবসা সম্পর্কিত ধারণা থাকে না। এই জাতীয় অ্যাক্সেস কেবল তখনই মঞ্জুর করা হয় যখন x
কোনও উদ্ভূত শ্রেণীর বা এটি থেকে প্রাপ্ত একটির সাথে সম্পর্কিত। এবং এটি যেকোন সুরক্ষিত সদস্যকে কেবল "থ্রো-অ্যাও" ক্লাস তৈরি করে সদস্যদের পড়ার জন্য নির্বিচারে কোডের টুকরোটিকে অনুমতি দিতে পারে, উদাহরণস্বরূপ std::stack
:
void f(std::stack<int> &s) {
// now, let's decide to mess with that stack!
struct pillager : std::stack<int> {
static std::deque<int> &get(std::stack<int> &s) {
// error: stack<int>::c is protected
return s.c;
}
};
// haha, now let's inspect the stack's middle elements!
std::deque<int> &d = pillager::get(s);
}
অবশ্যই, আপনি দেখছেন যে এর ফলে খুব বেশি ক্ষতি হতে পারে। তবে এখন, সদস্য পয়েন্টারগুলি এই সুরক্ষাটিকে অবরুদ্ধ করার অনুমতি দেয়! মূল বক্তব্যটি হ'ল সদস্য পয়েন্টারের ধরণটি সেই শ্রেণীর সাথে আবদ্ধ যার মধ্যে প্রকৃতপক্ষে বলা সদস্য থাকে - ঠিকানাটি নেওয়ার সময় আপনি যে ক্লাসটি নির্দিষ্ট করেছিলেন তা নয় । এটি আমাদের চেক অবরুদ্ধ করতে দেয়
struct A {
protected:
int a;
};
struct B : A {
// valid: *can* access protected member
static int get(A &x) { return x.*(&B::a); }
};
struct C : A { };
এবং অবশ্যই এটি std::stack
উদাহরণ সহ কাজ করে ।
void f(std::stack<int> &s) {
// now, let's decide to mess with that stack!
struct pillager : std::stack<int> {
static std::deque<int> &get(std::stack<int> &s) {
return s.*(pillager::c);
}
};
// haha, now let's inspect the stack's middle elements!
std::deque<int> &d = pillager::get(s);
}
উদ্ভূত শ্রেণিতে একটি ব্যবহারের ঘোষণার মাধ্যমে এটি আরও সহজ হতে চলেছে, যা সদস্যের নামটি পাবলিক করে এবং বেস শ্রেণীর সদস্যকে বোঝায়।
void f(std::stack<int> &s) {
// now, let's decide to mess with that stack!
struct pillager : std::stack<int> {
using std::stack<int>::c;
};
// haha, now let's inspect the stack's middle elements!
std::deque<int> &d = s.*(&pillager::c);
}
আর একটি লুকানো বৈশিষ্ট্য হ'ল আপনি শ্রেণিক অবজেক্টগুলিকে কল করতে পারেন যা ফাংশন পয়েন্টার বা রেফারেন্সে রূপান্তর করতে পারে। ওভারলোড রেজোলিউশন তাদের ফলস্বরূপ করা হয়, এবং যুক্তিগুলি পুরোপুরি এগিয়ে দেওয়া হয়।
template<typename Func1, typename Func2>
class callable {
Func1 *m_f1;
Func2 *m_f2;
public:
callable(Func1 *f1, Func2 *f2):m_f1(f1), m_f2(f2) { }
operator Func1*() { return m_f1; }
operator Func2*() { return m_f2; }
};
void foo(int i) { std::cout << "foo: " << i << std::endl; }
void bar(long il) { std::cout << "bar: " << il << std::endl; }
int main() {
callable<void(int), void(long)> c(foo, bar);
c(42); // calls foo
c(42L); // calls bar
}
এগুলিকে "সারোগেট কল ফাংশন" বলা হয়।
লুকানো বৈশিষ্ট্য:
যদি কোনও ফাংশন তার ব্যতিক্রম বিশদগুলিতে তালিকাভুক্ত নয় এমন একটি ব্যতিক্রম ছুঁড়ে ফেলে তবে ফাংশনটির std::bad_exception
তার ব্যতিক্রমের নির্দিষ্টকরণে ব্যতিক্রমটি রূপান্তরিত হয় std::bad_exception
এবং স্বয়ংক্রিয়ভাবে নিক্ষিপ্ত হয়। এইভাবে আপনি কমপক্ষে জানতে পারবেন যে একটি bad_exception
নিক্ষেপ করা হয়েছিল। এখানে আরও পড়ুন ।
ফাংশন চেষ্টা ব্লক
শ্রেণিবদ্ধ টেম্পলেটগুলিতে টাইপডেফগুলি বিঘ্নিত করতে টেমপ্লেট কীওয়ার্ড। যদি কোনও সদস্য টেমপ্লেট বিশেষীর নাম প্রদর্শিত হয় ক এর পরে.
, ->
অথবা ::
অপারেটর, এবং যে নাম স্পষ্টভাবে যোগ্যতাসম্পন্ন টেমপ্লেট পরামিতি, অভিব্যক্তি টেমপ্লেট দিয়ে উপসর্গ সদস্য টেমপ্লেট নাম আছে। এখানে আরও পড়ুন ।
ফাংশন প্যারামিটার ডিফল্ট রানটাইম সময়ে পরিবর্তন করা যেতে পারে। আরও পড়ুনএখানে ।
A[i]
হিসাবে ভাল হিসাবে কাজ করে i[A]
একটি শ্রেণীর অস্থায়ী উদাহরণগুলি সংশোধন করা যেতে পারে! কোনও অ-স্থায়ী সদস্য ফাংশনটি একটি অস্থায়ী অবজেক্টে আহ্বান করা যেতে পারে। উদাহরণ স্বরূপ:
struct Bar {
void modify() {}
}
int main (void) {
Bar().modify(); /* non-const function invoked on a temporary. */
}
আরও পড়ুন এখানে ।
যদি দুটি ভিন্ন ধরণের আগে এবং :
তারারারি ( ?:
) অপারেটরের এক্সপ্রেশনটিতে উপস্থিত থাকে, তবে এক্সপ্রেশনটির ফলে প্রাপ্ত প্রকারটিই দুটির মধ্যে সবচেয়ে সাধারণ। উদাহরণ স্বরূপ:
void foo (int) {}
void foo (double) {}
struct X {
X (double d = 0.0) {}
};
void foo (X) {}
int main(void) {
int i = 1;
foo(i ? 0 : 0.0); // calls foo(double)
X x;
foo(i ? 0.0 : x); // calls foo(X)
}
map::operator[]
কী অনুপস্থিত থাকলে এন্ট্রি তৈরি করে এবং ডিফল্ট-নির্মিত-নির্ধারিত প্রবেশ মূল্যকে রেফারেন্স দেয়। সুতরাং আপনি লিখতে পারেন:
map<int, string> m;
string& s = m[42]; // no need for map::find()
if (s.empty()) { // assuming we never store empty values in m
s.assign(...);
}
cout << s;
কতজন সি ++ প্রোগ্রামার এটি জানেন না তাতে আমি অবাক হয়েছি।
.find()
।
const map::operator[]
ত্রুটি বার্তা উত্পন্ন করে"
নামবিহীন নেমস্পেসে ফাংশন বা ভেরিয়েবলগুলি রাখলে static
সেগুলি ফাইলের সুযোগের মধ্যে সীমাবদ্ধ রাখার জন্য ব্যবহারকে হ্রাস করে।
static
বিশ্বব্যাপী সুযোগে কোনওভাবেই হ্রাস পাওয়া যায় না। (রেফারেন্সের জন্য: C ++ 03 §D.2)
static
ব্যবহার কেবলমাত্র শ্রেণিবদ্ধ বা ফাংশনের মধ্যে ব্যবহার করা উচিত।
ক্লাস টেম্পলেটগুলিতে সাধারণ বন্ধু ফাংশন সংজ্ঞায়িত করার জন্য বিশেষ মনোযোগ দেওয়া দরকার:
template <typename T>
class Creator {
friend void appear() { // a new function ::appear(), but it doesn't
… // exist until Creator is instantiated
}
};
Creator<void> miracle; // ::appear() is created at this point
Creator<double> oops; // ERROR: ::appear() is created a second time!
এই উদাহরণে, দুটি পৃথক তাত্পর্য দুটি অভিন্ন সংজ্ঞা তৈরি করে - এটি ওডিআর এর সরাসরি লঙ্ঘন
সুতরাং আমাদের অবশ্যই নিশ্চিত করতে হবে যে শ্রেণীর টেম্পলেটটির টেমপ্লেট প্যারামিটারগুলি সেই টেমপ্লেটে সংজ্ঞায়িত যে কোনও ফ্রেন্ড ফাংশনের প্রকারে উপস্থিত হয়েছে (যদি না আমরা একটি নির্দিষ্ট ফাইলে ক্লাস টেম্প্লেটের একাধিক ইনস্ট্যান্টেশন প্রতিরোধ করতে চাই তবে এটি অসম্ভাব্য নয়)। আসুন এটি আমাদের পূর্ববর্তী উদাহরণের পরিবর্তনে প্রয়োগ করুন:
template <typename T>
class Creator {
friend void feed(Creator<T>*){ // every T generates a different
… // function ::feed()
}
};
Creator<void> one; // generates ::feed(Creator<void>*)
Creator<double> two; // generates ::feed(Creator<double>*)
দাবি অস্বীকার: আমি এই বিভাগটি সি ++ টেম্পলেটগুলি থেকে আটকিয়েছি : সম্পূর্ণ গাইড / বিভাগ 8.4
অল্প পরিচিত, তবে নিম্নলিখিত কোডটি ঠিক আছে
void f() { }
void g() { return f(); }
নিম্নলিখিত অদ্ভুত চেহারা এক হিসাবে ভাল
void f() { return (void)"i'm discarded"; }
এ সম্পর্কে জেনে আপনি কিছু ক্ষেত্রে সুবিধা নিতে পারেন। একটি উদাহরণ: void
ফাংশনগুলি কোনও মান ফেরত দিতে পারে না তবে আপনি কেবল কিছুই ফিরিয়ে দিতে পারবেন না কারণ এগুলি শূন্যতার সাথে ইনস্ট্যান্ট করা যেতে পারে। স্থানীয় ভেরিয়েবলে মানটি সংরক্ষণের পরিবর্তে, যার ফলে ত্রুটি ঘটবে void
, কেবল একটি মান সরাসরি করুন return
template<typename T>
struct sample {
// assume f<T> may return void
T dosomething() { return f<T>(); }
// better than T t = f<T>(); /* ... */ return t; !
};
স্ট্রিংয়ের ভেক্টরে একটি ফাইল পড়ুন:
vector<string> V;
copy(istream_iterator<string>(cin), istream_iterator<string>(),
back_inserter(V));
vector<string> V((istream_iterator<string>(cin)), istream_iterator<string>());
- দ্বিতীয়
আপনি বিটফিল্ড টেমপ্লেট করতে পারেন।
template <size_t X, size_t Y>
struct bitfield
{
char left : X;
char right : Y;
};
আমি এখনও এর জন্য কোনও উদ্দেশ্য নিয়ে আসতে পারি নি, তবে হ্যাকের মতো এটি আমাকে অবাক করে দিয়েছে।
যে কোনও প্রোগ্রামিং ভাষার অন্যতম আকর্ষণীয় ব্যাকরণ।
এই তিনটি জিনিস এক সাথে সম্পর্কিত, এবং দুটি সম্পূর্ণ আলাদা কিছু ...
SomeType t = u;
SomeType t(u);
SomeType t();
SomeType t;
SomeType t(SomeType(u));
সকল কিন্তু তৃতীয় ও পঞ্চম একটি সংজ্ঞায়িত SomeType
স্ট্যাক বস্তু এবং এটি আরম্ভ (সঙ্গে u
একটি প্রথম দুই ক্ষেত্রে, এবং চতুর্থ ডিফল্ট কন্সট্রাকটর। তৃতীয় একটি ফাংশন যে কোন প্যারামিটার এবং আয় লাগে ঘোষণা করা হয় SomeType
। পঞ্চম একভাবে ঘোষণা করা হয় একটি ফাংশন যা SomeType
নামের ধরণের মান অনুসারে একটি পরামিতি নেয় u
।
ফরোয়ার্ড ঘোষণা থেকে মুক্তি পাওয়া:
struct global
{
void main()
{
a = 1;
b();
}
int a;
void b(){}
}
singleton;
সাথে সুইচ-বিবৃতি রচনা?: অপারেটর:
string result =
a==0 ? "zero" :
a==1 ? "one" :
a==2 ? "two" :
0;
একক লাইনে সবকিছু করা:
void a();
int b();
float c = (a(),b(),1.0f);
মেমসেট ছাড়াই জিরোং স্ট্রাক্ট:
FStruct s = {0};
সাধারনকরণ / মোড়ক কোণ- এবং সময়-মান:
int angle = (short)((+180+30)*65536/360) * 360/65536; //==-150
রেফারেন্স উল্লেখ:
struct ref
{
int& r;
ref(int& r):r(r){}
};
int b;
ref a(b);
int c;
*(int**)&a = &c;
FStruct s = {};
এমনকি আরও খাটো।
main
? আমি প্রস্তাব দিয়েছি global().main();
এবং কেবল সিঙ্গলটনের কথা ভুলে যাব ( আপনি কেবলমাত্র অস্থায়ী সাথে কাজ করতে পারেন, যা তার আজীবন প্রসারিত হয়ে
ত্রিশী শর্তসাপেক্ষ অপারেটরের ?:
"দ্বিতীয়" এবং "অনানুষ্ঠানিকভাবে কথা বলা" প্রকারের জন্য তার দ্বিতীয় এবং তৃতীয় অপারেন্ড দরকার। তবে এই প্রয়োজনীয়তার একটি ব্যতিক্রম রয়েছে (পাং উদ্দেশ্যে): দ্বিতীয় বা তৃতীয় অপারেন্ড হয় নিক্ষেপ এক্সপ্রেশন (যা টাইপযুক্ত) হতে পারেvoid
অন্য অপারেন্ডের ধরণের নির্বিশেষে, ) ।
অন্য কথায়, একটি ব্যবহার নিম্নলিখিত pefrectly বৈধ সি ++ এক্সপ্রেশন লিখতে পারেন ?:
অপারেটর
i = a > b ? a : throw something();
বিটিডাব্লু, থ্রো এক্সপ্রেশনটি আসলে একটি অভিব্যক্তি (টাইপের void
) এবং স্টেটমেন্ট নয় এটি সি ++ ভাষার আরও একটি অল্প-পরিচিত বৈশিষ্ট্য। এর অর্থ অন্যান্য জিনিসগুলির মধ্যে রয়েছে যে নিম্নলিখিত কোডটি পুরোপুরি বৈধ
void foo()
{
return throw something();
}
যদিও এটি এইভাবে করার পক্ষে খুব বেশি কিছু নেই (সম্ভবত কিছু জেনেরিক টেম্পলেট কোডে এটি কার্যকর হতে পারে)।
আধিপত্য বিধি কার্যকর, কিন্তু অল্প পরিচিত। এটি বলে যে বেস-ক্লাসের জালির মাধ্যমে কোনও অ-অনন্য পথের মধ্যেও, যদি কোনও সদস্য ভার্চুয়াল বেস-শ্রেণীর অন্তর্ভুক্ত থাকে তবে আংশিকভাবে লুকানো সদস্যের নাম অনুসন্ধান অনন্য:
struct A { void f() { } };
struct B : virtual A { void f() { cout << "B!"; } };
struct C : virtual A { };
// name-lookup sees B::f and A::f, but B::f dominates over A::f !
struct D : B, C { void g() { f(); } };
অ্যালাইনমেন্ট-সমর্থন বাস্তবায়নের জন্য আমি এটি ব্যবহার করেছি যা আধিপত্য বিধি দ্বারা স্বয়ংক্রিয়ভাবে কঠোর সারিবদ্ধকরণ খুঁজে বের করে।
এটি কেবল ভার্চুয়াল ফাংশনগুলিতেই প্রযোজ্য না, তবে টাইপডেফের নাম, স্থির / নন-ভার্চুয়াল সদস্য এবং অন্য যে কোনও কিছুতেও প্রযোজ্য। আমি এটি মেটা প্রোগ্রামগুলিতে ওভাররাইটযোগ্য বৈশিষ্ট্যগুলি প্রয়োগ করতে ব্যবহার করেছি।
struct C
আপনার উদাহরণের অন্তর্ভুক্ত কোনও বিশেষ কারণ ...? চিয়ার্স।