নাম অনুসারে সদস্য অ্যারেতে উপাদানগুলিতে অ্যাক্সেসের জন্য প্রক্সি শ্রেণি ব্যবহারের এক উপায়। এটি খুব সি ++, এবং সিনট্যাকটিক পছন্দ ব্যতীত রেফ-রিটার্নিং অ্যাকসেসর ফাংশনগুলির তুলনায় কোনও সুবিধা নেই। এটি ->
সদস্য হিসাবে উপাদানগুলিতে অ্যাক্সেস করতে অপারেটরটিকে ওভারলোড করে , তাই গ্রহণযোগ্য হওয়ার জন্য, উভয়কে অ্যাক্সেসরগুলির সিনট্যাক্স ( d.a() = 5;
) অপছন্দ করা দরকার , পাশাপাশি ->
একটি পয়েন্টারবিহীন বস্তু ব্যবহার করে সহ্য করা প্রয়োজন । আমি আশা করি এটি কোডের সাথে পরিচিত নয় এমন পাঠককেও বিভ্রান্ত করতে পারে, সুতরাং আপনি উত্পাদন করতে চান এমন কিছু থেকে এটি একটি ঝরঝরে কৌশল more
Data
এই কোডে struct হয় এছাড়াও সাবস্ক্রিপ্ট অপারেটর জন্য overloads, তার ভিতরে প্রবেশ ইন্ডেক্স উপাদান অন্তর্ভুক্ত ar
অ্যারের সদস্য, সেইসাথে begin
এবং end
ফাংশন, পুনরাবৃত্তির জন্য। এছাড়াও, এগুলি সমস্তই অবিচ্ছিন্ন এবং কনস্টের সংস্করণগুলির সাথে ওভারলোড হয়েছে, যা আমি সম্পূর্ণতার জন্য অন্তর্ভুক্ত করার প্রয়োজন বলে মনে করেছি।
যখন Data
's ->
নামে একটি উপাদান অ্যাক্সেস করতে (এই মত: ব্যবহার করা হয় my_data->b = 5;
), একটি Proxy
বস্তুর ফিরিয়ে দেওয়া হয়। তারপরে, কারণ এই Proxy
মূল্যমানটি কোনও পয়েন্টার নয়, এর নিজস্ব ->
অপারেটরটি স্বয়ংক্রিয়-চেইন- কলড , যা নিজেই একটি পয়েন্টারটি ফেরত দেয়। এইভাবে, Proxy
অবজেক্টটি তাত্ক্ষণিক হয় এবং প্রাথমিক অভিব্যক্তির মূল্যায়নের সময় বৈধ থাকে।
একটি এর Contruction Proxy
বস্তুর তার 3 রেফারেন্স সদস্যদের মান a
, b
এবং c
একটি পয়েন্টার কন্সট্রাকটর পাস, যা একটি বাফার অন্তত 3 মান যার টাইপ টেমপ্লেট প্যারামিটার হিসাবে দেওয়া হয় ধারণকারী বিন্দু অধিকৃত হয় অনুযায়ী T
। সুতরাং Data
ক্লাসের সদস্য হওয়া নামকৃত রেফারেন্সগুলি ব্যবহার করার পরিবর্তে, রেফারেন্সগুলি অ্যাক্সেসের পয়েন্টে পপুলেশন করে স্মৃতি সাশ্রয় করে (তবে দুর্ভাগ্যক্রমে, অপারেটরটি ব্যবহার করে ->
নয় .
)।
সংকলকটির অপ্টিমাইজারটি কতটা ভালভাবে ব্যবহারের মাধ্যমে প্রবর্তিত সমস্ত দিকনির্দেশকে সরিয়ে দেয় তা পরীক্ষা করার জন্য Proxy
, নীচের কোডটিতে 2 টি সংস্করণ রয়েছে main()
। #if 1
সংস্করণ ব্যবহার করে ->
এবং []
অপারেটর এবং #if 0
সংস্করণ পদ্ধতি সমতুল্য সেট সঞ্চালিত, কিন্তু শুধুমাত্র সরাসরি অ্যাক্সেস করার মাধ্যমে Data::ar
।
Nci()
ফাংশন অ্যারে উপাদান, যা সরাসরি প্রতিটি মধ্যে ধ্রুবক মান প্লাগিং থেকে অপটিমাইজার বাধা দেয় আরম্ভের জন্য রানটাইম পূর্ণসংখ্যা মান উত্পন্ন std::cout
<<
কল।
জিসিসি 6.2 এর জন্য, -O3 ব্যবহার করে, উভয় সংস্করণ main()
একই সমাবেশ তৈরি করে ( প্রথমটির সাথে তুলনা করার আগে #if 1
এবং #if 0
আগে টগল main()
করুন): https://godbolt.org/g/QqRWZb
#include <iostream>
#include <ctime>
template <typename T>
class Proxy {
public:
T &a, &b, &c;
Proxy(T* par) : a(par[0]), b(par[1]), c(par[2]) {}
Proxy* operator -> () { return this; }
};
struct Data {
int ar[3];
template <typename I> int& operator [] (I idx) { return ar[idx]; }
template <typename I> const int& operator [] (I idx) const { return ar[idx]; }
Proxy<int> operator -> () { return Proxy<int>(ar); }
Proxy<const int> operator -> () const { return Proxy<const int>(ar); }
int* begin() { return ar; }
const int* begin() const { return ar; }
int* end() { return ar + sizeof(ar)/sizeof(int); }
const int* end() const { return ar + sizeof(ar)/sizeof(int); }
};
// Nci returns an unpredictible int
inline int Nci() {
static auto t = std::time(nullptr) / 100 * 100;
return static_cast<int>(t++ % 1000);
}
#if 1
int main() {
Data d = {Nci(), Nci(), Nci()};
for(auto v : d) { std::cout << v << ' '; }
std::cout << "\n";
std::cout << d->b << "\n";
d->b = -5;
std::cout << d[1] << "\n";
std::cout << "\n";
const Data cd = {Nci(), Nci(), Nci()};
for(auto v : cd) { std::cout << v << ' '; }
std::cout << "\n";
std::cout << cd->c << "\n";
//cd->c = -5; // error: assignment of read-only location
std::cout << cd[2] << "\n";
}
#else
int main() {
Data d = {Nci(), Nci(), Nci()};
for(auto v : d.ar) { std::cout << v << ' '; }
std::cout << "\n";
std::cout << d.ar[1] << "\n";
d->b = -5;
std::cout << d.ar[1] << "\n";
std::cout << "\n";
const Data cd = {Nci(), Nci(), Nci()};
for(auto v : cd.ar) { std::cout << v << ' '; }
std::cout << "\n";
std::cout << cd.ar[2] << "\n";
//cd.ar[2] = -5;
std::cout << cd.ar[2] << "\n";
}
#endif