c++ - দুটি শূন্য-আরগ কনস্ট্রাক্টরকে আলাদা করার আইডোমেটিক উপায়




performance constructor (5)

আপনার ইতিমধ্যে সমাধানটি সঠিক এবং আমি আপনার কোডটি পর্যালোচনা করছি কিনা তা দেখতে আমি ঠিক দেখতে চাই। এটি যতটা সম্ভব দক্ষ, স্পষ্ট এবং সংক্ষিপ্ত।

আমার এই জাতীয় ক্লাস রয়েছে:

struct event_counts {
    uint64_t counts[MAX_COUNTERS];

    event_counts() : counts{} {}

    // more stuff

};

সাধারণত আমি প্রদর্শিত হিসাবে counts অ্যারে ডিফল্ট (শূন্য) করতে চাই।

প্রোফাইলিং দ্বারা চিহ্নিত নির্বাচিত স্থানে যাইহোক, আমি অ্যারে সূচনাটি দমন করতে চাই, কারণ আমি জানি অ্যারে ওভাররাইট করা প্রায় শেষ, তবে সংকলকটি এটি বের করার মতো স্মার্ট নয়।

এই জাতীয় "গৌণ" শূন্য-আরগ নির্মাণকারীকে তৈরি করার একটি মূর্ত ও কার্যকর উপায় কী?

বর্তমানে, আমি ট্যাগ ক্লাস uninit_tag ব্যবহার করছি যা একটি ডামি আর্গুমেন্ট হিসাবে পাস করা হয়:

struct uninit_tag{};

struct event_counts {
    uint64_t counts[MAX_COUNTERS];

    event_counts() : counts{} {}

    event_counts(uninit_tag) {}

    // more stuff

};

তারপরে আমি ইভেন্ট- event_counts c(uninit_tag{}); মতো নো- event_counts c(uninit_tag{}); কনস্ট্রাক্টরকে কল করি event_counts c(uninit_tag{}); যখন আমি নির্মাণ দমন করতে চাই।

আমি এমন সমাধানগুলিতে উন্মুক্ত যা কোনও ডামি ক্লাস তৈরির সাথে জড়িত নয় বা কোনওভাবে আরও দক্ষ ইত্যাদি etc.


আপনি আপনার শ্রেণীর জন্য একটি দ্বি-পর্যায়ে সূচনা বিবেচনা করতে চাইতে পারেন:

struct event_counts {
    uint64_t counts[MAX_COUNTERS];

    event_counts() = default;

    void set_zero() {
       std::fill(std::begin(counts), std::end(counts), 0u);
    }
};

উপরের কনস্ট্রাক্টর অ্যারের শূন্য থেকে আরম্ভ করে না। অ্যারের উপাদানগুলিকে শূন্যতে সেট করতে, আপনাকে নির্মাণের পরে সদস্য ফাংশন set_zero() কল করতে হবে।


আমি এটি এইভাবে করব:

struct event_counts {
    uint64_t counts[MAX_COUNTERS];

    event_counts() : counts{} {}

    event_counts(bool initCounts) {
        if (initCounts) {
            std::fill(counts, counts + MAX_COUNTERS, 0);
        }
    }
};

event_counts(false) আপনি যখন event_counts(false) ব্যবহার event_counts(false) তখন সমস্ত কোড এড়িয়ে যেতে যথেষ্ট স্মার্ট হবে এবং আপনার শ্রেণীর ইন্টারফেসটিকে এত অদ্ভুত করার পরিবর্তে আপনি কী বোঝাতে চেয়েছেন তা ঠিকই বলতে পারেন।


আমি কেবল একটি টাইপিং কিছুটা সংরক্ষণ করতে একটি সাবক্লাস ব্যবহার করব:

struct event_counts {
    uint64_t counts[MAX_COUNTERS];

    event_counts() : counts{} {}
    event_counts(uninit_tag) {}
};    

struct event_counts_no_init: event_counts {
    event_counts_no_init(): event_counts(uninit_tag{}) {}
};

আপনি bool বা int বা অন্য কোনও কিছুর সাথে bool কনস্ট্রাক্টরের যুক্তি পরিবর্তনের মাধ্যমে ডামি ক্লাস থেকে মুক্তি পেতে পারেন, কারণ এটি আর স্মৃতিবিজড়িত হওয়ার দরকার নেই।

আপনি উত্তরাধিকারের আশেপাশে অদলবদল করতে পারেন এবং events_count_no_init তাদের উত্তরে প্রস্তাবিত একটি ডিফল্ট events_count_no_init সাথে সংজ্ঞা দিতে পারেন এবং তারপরে events_count সাবক্লাস হতে পারে:

struct event_counts_no_init {
    uint64_t counts[MAX_COUNTERS];
    event_counts_no_init() = default;
};

struct event_counts: event_counts_no_init {
    event_counts(): event_counts_no_init{} {}
};

যদি কনস্ট্রাক্টর বডি খালি থাকে তবে এটি বাদ দেওয়া বা ডিফল্ট করা যেতে পারে:

struct event_counts {
    std::uint64_t counts[MAX_COUNTERS];
    event_counts() = default;
};

তারপরে ডিফল্ট সূচনা event_counts counts; event_counts counts{}; counts.counts ছেড়ে counts.counts ( counts.counts ডিফল্ট ইনিশিয়ালাইশনটি এখানে কোনও বিকল্প নেই), এবং মান event_counts counts{}; কার্যকরভাবে এটি জিরো দিয়ে পূরণ করে counts.counts আরম্ভ করার মান দেবে।





constructor