সি ++ 11 এ অটো_পিটার অবমূল্যায়নের জন্য ডিজাইন পরিবর্তনগুলি কীভাবে পরিচালনা করবেন?


12

আমরা সি ++ 11 (অর্থাত্ -std=c++11) এর অধীনে একটি লাইব্রেরি পরীক্ষা করছি । গ্রন্থাগারটি ব্যবহার করে auto_ptrএবং এই প্যাটার্ন:

Foo* GetFoo()
{
    autoptr<Foo> ptr(new Foo);

    // Initialize Foo
    ptr->Initialize(...);

    // Now configure remaining attributes
    ptr->SomeSetting(...);

    return ptr.release();
}

সি ++ 11 অবনমিত হয়েছে auto_ptr, তাই আমরা এটি থেকে সরে যেতে চাই।

তবে কোডটি সি ++ 03 এবং সি ++ 11 উভয়ই সমর্থন করে, তাই এটি ইয়াঙ্কিংয়ের মতো সহজ নয় auto_ptr। এটি উল্লেখযোগ্য যে লাইব্রেরির কোনও বাহ্যিক নির্ভরতা নেই। এটি সি ++ 03 ব্যবহার করে; এবং অটটুলস, কমাক, বুস্ট, ... ব্যবহার করে না

auto_ptrসি ++ ১১ এর সাথে সামঞ্জস্যতা বজায় রেখে কীভাবে আমাদের সি ++ 11 থেকে সরে যেতে ডিজাইন পরিবর্তনগুলি হ্যান্ডেল করা উচিত ?


auto_ptrস্কোপড (যথা std::auto_ptr) এর কি কোনও , তাদের কি দরকার হয় বা স্মার্ট পয়েন্টারটি অন্য কোনও নেমস্পেস থেকে নেওয়া যেতে পারে?
নিলাল

সরাইয়া হিসাবে, আপনি Foo::Initializeমধ্যে ভাঁজ করতে পারেন Foo::Foo
এমসাল্টারস

1
@ এসএমএলটাররা - হ্যাঁ, এটি সম্পর্কে আমি সর্বদা হালকা অস্বস্তি বোধ করি of নব্বইয়ের দশকে গ্রন্থাগারটি নকশা করা হয়েছিল এবং আমি মনে করি যে নকশাটি এমএফসির অনুরূপ ছিল। এটি হল, নিম্ন স্তরের সি ++ নির্মাণ ছিল এবং তারপরে একটি "উচ্চ স্তরের" অবজেক্ট নির্মাণ। আমি মনে করি বৈশিষ্ট্যটি ট্রেডঅফ হিসাবে ব্যবহৃত হয়েছিল যাতে ক্লাসে 6 বা 12 টি আলাদা কনস্ট্রাক্টর না থাকে। (এই মুহুর্তে, আমি যা করেছি তা পেরেছি এবং নিশ্চিত হয়েছি যে পিওডি টাইপের সদস্য ভেরিয়েবলগুলি সি ++ কনস্ট্রাক্টরগুলিতে বোধগম্য ডিফল্ট হিসাবে শুরু করা হবে)।

উত্তর:


13

বেশিরভাগ ক্ষেত্রেই এর std::unique_ptrপরিবর্তে (তবে নিরাপদ) প্রতিস্থাপনের জন্য তৈরি করা হয়েছিল std::auto_ptr, সুতরাং কোডটি ব্যবহারের নির্দেশনা unique_ptrবা (যেমন আপনি জিজ্ঞাসা করছেন) ব্যতীত অন্য খুব কম কোডের পরিবর্তন (যদিও যদি থাকে) হওয়া উচিত auto_ptr

এটি করার কয়েকটি উপায় রয়েছে (এবং প্রতিটি তার নিজস্ব তালিকার বাণিজ্য নিয়ে আসে) নীচে। প্রদত্ত কোডের নমুনা দেওয়া, আমি প্রথম দুটি বিকল্পের যে কোনওটির পক্ষে চাই

বিকল্প 1

#if __cplusplus >= 201103L
template <typename T>
using auto_ptr = std::unique_ptr<T>;
#else
using std::auto_ptr;
#endif

Tradeoffs;

  • আপনি auto_ptrবিশ্বব্যাপী নেমস্পেসে নামটি প্রবর্তন করেন ; আপনি এটি আপনার নিজস্ব "ব্যক্তিগত" নাম স্থানটি নির্ধারণ করে এটিকে প্রশমিত করতে পারেন
  • একবার সি ++ 17 এ স্থানান্তরিত করুন (আমার বিশ্বাস auto_ptrপুরোপুরি মুছে ফেলা হবে) আপনি আরও সহজে অনুসন্ধান এবং প্রতিস্থাপন করতে পারেন

বিকল্প 2

template <typename T>
struct my_ptr {
    #if __cplusplus >= 201103L
    typedef std::unique_ptr<T> ptr;
    #else
    typedef std::auto_ptr<T> ptr;
    #endif
};

Tradeoffs;

  • সম্ভবত আরও জটিল হয়ে কাজ করার জন্য, সমস্ত বর্তমানের কোডটিতে auto_ptrকিছু পরিবর্তন করার মতো দরকারmy_ptr<T>::ptr
  • সুরক্ষার চেয়ে আরও ভাল নাম বিশ্বব্যাপী নেমস্পেসে প্রবেশ করা হচ্ছে না

বিকল্প 3

কিছুটা বিতর্কিত, তবে আপনি যদি stdবেস হিসাবে একটি শ্রেণি থাকার ক্যাভ্যাটগুলি সহ্য করতে প্রস্তুত হন

#if __cplusplus >= 201103L
template <typename T>
using my_ptr = std::unique_ptr<T>;
#else
template <typename T>
class my_ptr : public std::auto_ptr<T> {
  // implement the constructors for easier use
  // in particular
  explicit my_ptr( X* p = 0 ) : std::auto_ptr(p) {}
};
#endif

Tradeoffs;

  • উত্তরাধিকার সূত্রে প্রাপ্ত শ্রেণিটি ব্যবহার করার চেষ্টা করবেন না যেখানে ভার্চুয়াল বেস (বিশেষত কব্জিটি নন-ভার্চুয়াল ডেস্ট্রাক্টর) আশা করা যায়। এটি ক্ষেত্রে সমস্যা হওয়া উচিত নয় - তবে এটি সম্পর্কে সচেতন হন
  • আবার কোড পরিবর্তন হয়
  • সম্ভাব্য নেমস্পেসের মিল নেই - এটি সমস্ত কীভাবে পয়েন্টার শ্রেণিটি শুরু করতে ব্যবহৃত হয় তার উপর নির্ভর করে

বিকল্প 4

পয়েন্টারগুলিকে একটি নতুন ক্লাসে মোড়ক করুন এবং প্রয়োজনীয় ফাংশন সদস্যকে একত্রিত করুন

template <typename T>
class my_ptr { // could even use auto_ptr name?
  #if __cplusplus >= 201103L
  std::unique_ptr<T> ptr_;
  #else
  std::auto_ptr<T> ptr_;
  #endif

  // implement functions required...
  T* release() { return ptr_.release(); }
};

Tradeoffs;

  • কিছুটা চরম যখন আপনি সত্যিই চান তা হ'ল বাস্তবায়নগুলি "বদলানো"

খুব ভাল উত্তর। আমি আসলে এটি কিছুটা গবেষণা করেছি এবং আপনি চেষ্টা করেছিলাম এমন পরীক্ষাগুলির মধ্যে কমপক্ষে তিনটি আঘাত করেছিলেন। (আপনি কি অভাব OS X এবং ঝনঝন নির্দিষ্ট উপাদান OS X এর একটি ভালুক কারন এটিতে এখনও সি ++ সময়ে 03 জন্য TR1 নামস্থান ব্যবহার করে, এবং আপনি এই পদ্ধতি ব্যবহার করে কিছু অন্তর্ভুক্ত করা আছে। কোন প্রকার নামস্থানে 'unique_ptr' নামক 'এসডিডি' এলএলভিএম / কলং এর অধীনে সংকলন করার সময় )।

@jww। আমি ওএস এক্স (এক্সকোড 6.4 এবং অ্যাপল এলএলভিএম সংস্করণ 6.1.0 (ক্ল্যাং-602.0.53) (এলএলভিএম 3.6.0svn এর উপর ভিত্তি করে) এ আছি এবং নাম + স্পেস নম্বর বাদে সি ++ 03/11 মিক্স নিয়ে কোনও সমস্যা tr1নেই আর সেখানে থাকাকালীন (আমি libc ++ ব্যবহার করি এবং libstdc ++ ব্যবহার করি না)। আমি জানি যে টিআর 1 অ-আদর্শিক ছিল, তবে আমি খসড়া (এখানে) কোথাও খুঁজে পাচ্ছি না যে ফাইলগুলি একেবারে <tr1/...>থাকতে হবে, বাস্তবে এটি কেবলমাত্র শিরোনামে থাকা <memory>ফাইল ইত্যাদি নামমাত্রে উল্লেখ করেছে tr1
নিলাল

@jww। আমি অনুমান করি যে সংকলক, গ্রন্থাগার এবং লক্ষ্য ডিভাইসের একটি নির্দিষ্ট মিশ্রণ দেওয়া হয়েছে - আপনাকে আরও কয়েকটি হাত স্ট্যান্ড করার প্রয়োজন হতে পারে। অন্যথায়, ওএস এক্স-এ, ঝনঝন এবং libc ++ এ সরানো বিবেচনা করুন। স্পষ্টভাবে আমি libc ++ কে ওএস এক্স-এর নতুন "নেটিভ" সি ++ গ্রন্থাগার হিসাবে বিবেচনা করি - আমি এটিতে ডিফল্ট হই। এই দাবিগুলি সমর্থন করার মতো আমার কাছে আর কোনও উপায় নেই যে ঝনঝন / অ্যাপল সম্পর্কের ইতিহাস এবং ওএস এক্স-এর জিসিসি সরঞ্জামগুলি পুরানো (লাইব্রেরি) মনে হয়েছে বা সবে সরে গেছে (যতদূর আমি জানি যে জিসিসি যাইহোক ঝাঁকুনির জন্য একটি পাতলা স্টাব) )।
নিলাল

"অন্যথায়, ওএস এক্স-এ, ঝনঝন এবং libc ++ এ চলে যাওয়ার কথা বিবেচনা করুন - " হ্যাঁ, আমি আপনার সাথে একমত। যাইহোক, আমরা ব্যবহারকারীদের সেই পছন্দটি করতে এবং তাদের উপর জোর না করে দিতে চাই। (যখন তারা নির্দিষ্ট করে (বা অভাব থাকে) তখন তারা স্পষ্টতই পছন্দ করে নিন CXX=...

এখানে ক্ষেত্রে যে হয় আমাকে OS X এর 10.7 এবং 10.8 এত সমস্যা ঘটাচ্ছে আছে: c++ -v -std=c++11 -x c++ - < /dev/null। আমি grep'dফেলে দেওয়া ডিরেক্টরিগুলি অন্তর্ভুক্ত করি এবং সেগুলি অন্তর্ভুক্ত হয় নাunique_ptr

0

বিকল্প 5: ডাইরেক্ট ওরফে

#if __cplusplus >= 201103L
template<typename T> 
using MyPtr = std::unique_ptr<T>;
#else 
#define MyPtr std::auto_ptr
#endif 

Tradeoffs:

  1. নতুন ভাষার সংস্করণগুলির জন্য, একে একে সি ++ 11 এবং তারপরে, সঠিক নামের স্মার্ট পয়েন্টারে আপনার ওরফে টাইপ ম্যাপ। যে কোনও ব্যবহারকারীর কোড যা আসলে এসডিডি :: অটো_পিটার সম্পর্কিত নির্দিষ্ট এপিআইয়ের উপর নির্ভর করে সংকলক দ্বারা পতাকাঙ্কিত হবে, এটি চূড়ান্ত গ্যারান্টি এটি সত্যই স্থির হয়ে যাবে।

  2. লিগ্যাসি সি ++ 03 মোডে টাইপ উপন্যাসটি একটি ম্যাক্রো। এটি মোটামুটি, তবে ফলাফলটি বাক্য গঠন MyPtr<T>বাকী কোডের পুরো অংশে C ++ 11 ক্ষেত্রে সাদৃশ্যপূর্ণ।

  3. এটি MyPtrসেট আপ করার জন্য আপনাকে আপনার সমস্ত অটো_পিটার ভেরিয়েবলগুলি সন্ধান এবং পরিবর্তন করতে হবে।


1
এটি খুব স্পষ্ট নয় যে এটি কী উল্লেখ করছে (এবং, যেমন বলা হচ্ছে এটি কোনও প্রশ্ন নয়)।
16:54

1
@ অটোফেজ আমি এর উত্তর বিশ্বাস করি ... তাই সম্ভবত কোনও প্রশ্ন নয়।
Kain0_0
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.