সি ++ শূন্য সূচনা - কেন এই প্রোগ্রামটিতে `b unin অবিচ্ছিন্ন, তবে` a` আরম্ভ হয়?


135

এই স্ট্যাক ওভারফ্লো প্রশ্নের জন্য গৃহীত (এবং শুধুমাত্র) উত্তর অনুসারে ,

সাথে কনস্ট্রাক্টর সংজ্ঞায়িত করা হচ্ছে

MyTest() = default;

পরিবর্তে বস্তু শূন্য-আরম্ভ হবে।

তাহলে নিম্নলিখিতগুলি কেন করে?

#include <iostream>

struct foo {
    foo() = default;
    int a;
};

struct bar {
    bar();
    int b;
};

bar::bar() = default;

int main() {
    foo a{};
    bar b{};
    std::cout << a.a << ' ' << b.b;
}

এই আউটপুট উত্পাদন:

0 32766

নির্ধারিত উভয় কনস্ট্রাক্টর ডিফল্ট? রাইট? এবং পিওডি ধরণের জন্য, ডিফল্ট সূচনাটি শূন্য-আরম্ভ হয়।

এবং এই প্রশ্নের গৃহীত উত্তর অনুযায়ী ,

  1. যদি কোনও পিওডি সদস্য কনস্ট্রাক্টরে বা সি ++ 11 ইন-ক্লাস ইনিশিয়ালাইজেশনের মাধ্যমে আরম্ভ না করা হয় তবে এটি ডিফল্ট-আরম্ভ হয়।

  2. উত্তর স্ট্যাক বা গাদা নির্বিশেষে একই।

  3. সি ++ 98 এ (এবং পরে নয়), নতুন ইনট () শূন্য সূচনা করার জন্য নির্দিষ্ট করা হয়েছিল।

আমার ( ক্ষুদ্রতর হলেও ) মাথাটি ডিফল্ট নির্মাণকারী এবং ডিফল্ট সূচনাতে চারপাশে মোড়ানোর চেষ্টা করা সত্ত্বেও আমি কোনও ব্যাখ্যা দিয়ে আসতে পারিনি।


3
মজার বিষয় হচ্ছে, আমি বি এর জন্য একটি সতর্কতাও পেয়েছি: main.cpp: 18: 34: সতর্কতা: 'বি.বার :: বি' এই ফাংশনে অবিচ্ছিন্নভাবে ব্যবহার করা হয়েছে [-উইনিটায়ালাইজড] coliru.stacked-Crooked.com/a/d1b08a4d6fb4ca7e
tkausl

8
barএর কনস্ট্রাক্টর ব্যবহারকারীর সরবরাহ করা হয় যেখানে fooকনস্ট্রাক্টর ডিফল্ট হয়।
Jarod42

2
@ পেটবেকার, আমি এটি বুঝতে পারি। আমি কীভাবে কোনওভাবে আমার র‍্যামকে কিছুটা নাড়াতে পারি যাতে সেখানে যদি শূন্য থাকে তবে এটি এখন অন্য কিছু হওয়া উচিত। ;) পিএস আমি এক ডজনবার প্রোগ্রাম চালিয়েছি। এটি কোনও বড় প্রোগ্রাম নয়। আপনি এটি চালাতে এবং এটি আপনার সিস্টেমে পরীক্ষা করতে পারেন। aশূন্য। bএটি না. দেখে মনে aহচ্ছে আরম্ভ করা হয়েছে।
ডক

2
@ জোয়েম্যালোন "এটি ব্যবহারকারী-কীভাবে সরবরাহ করা হয়" সম্পর্কিত: এর সংজ্ঞাটি যে bar::bar()দৃশ্যমান main()তা কোনও পৃথক সংকলনের ইউনিটে সংজ্ঞায়িত হতে পারে এবং main()কেবলমাত্র ঘোষণাপত্রটি দৃশ্যমান অবস্থায় খুব অ-তুচ্ছ কিছু করতে পারে তার কোনও গ্যারান্টি নেই । আমি মনে করি আপনি সম্মত হবেন যে আপনি bar::bar()পৃথক সংকলন ইউনিটে আপনার সংজ্ঞা স্থাপন করেছেন কিনা তা নির্ভর করে এই আচরণটি পরিবর্তন করা উচিত নয় (এমনকি পুরো পরিস্থিতিটি অনিচ্ছুক হলেও)।
ম্যাক্স ল্যাংফোফ

2
@ বালকি বা int a = 0;আপনি কি সত্যই স্পষ্ট হতে চান?
নাথান অলিভার

উত্তর:


109

এখানে বিষয়টি বেশ সূক্ষ্ম। আপনি এটা ভাববেন

bar::bar() = default;

আপনাকে একটি সংকলক উত্পন্ন ডিফল্ট কনস্ট্রাক্টর দেবে, এবং এটি করে তবে এটি এখন ব্যবহারকারী হিসাবে বিবেচিত। [dcl.fct.def.default] / 5 টি বলে:

সুস্পষ্টভাবে ডিফল্ট ফাংশন এবং সুস্পষ্টভাবে ঘোষিত ফাংশনগুলিকে সম্মিলিতভাবে ডিফল্ট ফাংশন বলা হয়, এবং বাস্তবায়ন তাদের জন্য অন্তর্ভুক্ত সংজ্ঞা প্রদান করে ([class.ctor] [class.dtor], [class.copy.ctor], [class.copy.assign ]), যার অর্থ মুছে ফেলা হিসাবে তাদের সংজ্ঞা দেওয়া হতে পারে। কোনও ফাংশনটি ব্যবহারকারী-সরবরাহিত হয় যদি এটি ব্যবহারকারী-ঘোষিত হয় এবং তার প্রথম ঘোষণায় স্পষ্টতই খেলাপি বা মুছে ফেলা হয় না।একটি ব্যবহারকারী দ্বারা সরবরাহিত স্পষ্টতই-খেলাপী কার্য (যেমন, তার প্রথম ঘোষণার পরে স্পষ্টতই খেলাপী) এমন স্থানে সংজ্ঞায়িত করা হয় যেখানে এটি স্পষ্টতই খেলাপি হয়; যদি এই জাতীয় কোনও ফাংশন স্পষ্টভাবে মুছে ফেলা হিসাবে সংজ্ঞায়িত করা হয় তবে প্রোগ্রামটি নিরবচ্ছিন্ন। [দ্রষ্টব্য: কোনও ক্রিয়াকলাপটিকে তার প্রথম ঘোষণার পরে খেলাপি হিসাবে ঘোষিত করা কার্যকর কার্যকর কার্যকরকরণ এবং সংক্ষিপ্ত সংজ্ঞা প্রদান করতে পারে যখন একটি বিবর্তিত কোড বেসে স্থিতিশীল বাইনারি ইন্টারফেস সক্ষম করে। - শেষ নোট]

জোর আমার

সুতরাং আমরা দেখতে পাচ্ছি যেহেতু আপনি bar()যখন প্রথম ঘোষণা করেছিলেন তখন আপনি ডিফল্ট হননি , এখন এটি ব্যবহারকারী সরবরাহিত হিসাবে বিবেচিত। কারণ [dcl.init] /8.2

যদি টি কোনও ব্যবহারকারীর সরবরাহিত বা মুছে ফেলা ডিফল্ট কনস্ট্রাক্টর ছাড়াই (সম্ভবত সিভি-কোয়ালিটিভড) শ্রেণীর ধরণের হয় তবে অবজেক্টটি শূন্য-আরম্ভ হয় এবং ডিফল্ট-আরম্ভের জন্য শব্দার্থ সীমাবদ্ধতাগুলি পরীক্ষা করা হয়, এবং টিতে যদি একটি তুচ্ছ ত্রুটিযুক্ত ডিফল্ট নির্মাণকারী থাকে , অবজেক্টটি ডিফল্ট-আরম্ভীকৃত;

আর প্রযোজ্য নয় এবং আমরা আরম্ভের মান নয় bবরং এর পরিবর্তে [dcl.init] /8.1 অনুযায়ী এটি ডিফল্ট সূচনা করব

যদি টি হ'ল (সম্ভবত সিভি-কোয়ালিফাইড) শ্রেণীর ধরণ ([শ্রেণী]) হয় তবে কোনও ডিফল্ট কনস্ট্রাক্টর ([class.default.ctor]) বা ব্যবহারকারী-সরবরাহিত বা মুছে ফেলা কোনও ডিফল্ট কনস্ট্রাক্টর থাকে তবে অবজেক্টটি ডিফল্ট-আরম্ভ হয় ;


52
মানে (*_*).... এমনকি যদি ভাষাটির মৌলিক নির্মাণগুলিও ব্যবহার করতে হয়, তবে ভাষা খসড়ার সূক্ষ্ম মুদ্রণটি আমার পড়া দরকার, তবে হাল্লুজাহ! তবে সম্ভবত আপনি যা বলছেন তা মনে হয়।
হাঁস

12
@ বালকি হ্যাঁ, bar::bar() = defaultলাইন ছাড়াই করানো bar::bar(){}ইনলাইন করা সমান ।
নাথান অলিভার

15
@ জোয়েম্যালোন হ্যাঁ, সি ++ বেশ জটিল হতে পারে। আমি নিশ্চিত না যে এর কারণ কী।
নাথান অলিভার

3
যদি পূর্বের ঘোষণা থাকে, তবে ডিফল্ট কীওয়ার্ড সহ পরবর্তী সংজ্ঞাটি সদস্যদের শূন্য করবে না। রাইট? এটা সঠিক। এটি এখানে যা ঘটছে তা হচ্ছে।
নাথান অলিভার

6
কারণটি আপনার উদ্ধৃতিতে ঠিক আছে: একটি লাইন ডিফল্ট ডিফল্টের বিন্দুটি হ'ল "একটি বিকশিত কোড বেসে স্থিতিশীল বাইনারি ইন্টারফেস সক্ষম করার সময় দক্ষ সম্পাদন এবং সংক্ষিপ্ত সংজ্ঞা প্রদান", অন্য কথায়, আপনাকে স্যুইচ করতে সক্ষম করুন এটিবিআইকে না ভেঙে পরে প্রয়োজনে ব্যবহারকারী-লিখিত সংস্থা। মনে রাখবেন যে সীমার বাইরে সংজ্ঞাটি অন্তর্নিহিত নয় এবং তাই কেবলমাত্র একটি টিইউতে ডিফল্টরূপে উপস্থিত হতে পারে; ক্লাসের সংজ্ঞা একা দেখে অন্য একটি টিইউ এর স্পষ্টভাবে ডিফল্ট হিসাবে সংজ্ঞায়িত হয়েছে কিনা তা জানার কোনও উপায় নেই।
টিসি

25

আচরণের পার্থক্য যে, অনুযায়ী থেকে আসে [dcl.fct.def.default]/5, bar::barহয় ব্যবহারকারী প্রদত্ত যেখানে foo::fooনয় 1 । ফলত, foo::fooহবে ভ্যালু আরম্ভ তার সদস্যদের (অর্থাত: শূন্য আরম্ভ foo::a ) কিন্তু bar::baruninitialized থাকবে 2


1) [dcl.fct.def.default]/5

কোনও ফাংশনটি ব্যবহারকারী-সরবরাহিত হয় যদি এটি ব্যবহারকারী-ঘোষিত হয় এবং তার প্রথম ঘোষণায় স্পষ্টতই খেলাপি বা মুছে ফেলা হয় না।

2)

থেকে [dcl.init # 6] :

টি টাইপের কোনও অবজেক্টের মূল্য-সূচনা করার জন্য:

  • যদি টি হ'ল (সম্ভবত সিভি-কোয়ালিফাইড) শ্রেণীর ধরণের, যেখানে কোনও ডিফল্ট কনস্ট্রাক্টর ([শ্রেণি.ক্টর]) বা একটি ডিফল্ট কনস্ট্রাক্টর নেই যা ব্যবহারকারী দ্বারা সরবরাহ করা বা মুছে ফেলা হয় তবে অবজেক্টটি ডিফল্ট-আরম্ভ হয়;

  • যদি টি কোনও ব্যবহারকারীর সরবরাহিত বা মুছে ফেলা ডিফল্ট কনস্ট্রাক্টর ছাড়াই (সম্ভবত সিভি-কোয়ালিটিভড) শ্রেণীর ধরণের হয় তবে অবজেক্টটি শূন্য-আরম্ভ হয় এবং ডিফল্ট-আরম্ভের জন্য শব্দার্থ সীমাবদ্ধতাগুলি পরীক্ষা করা হয়, এবং টিতে যদি একটি তুচ্ছ ত্রুটিযুক্ত ডিফল্ট নির্মাণকারী থাকে , অবজেক্টটি ডিফল্ট-আরম্ভীকৃত;

  • ...

থেকে [dcl.init.list] :

টি-এর একটি অবজেক্টের রেফারেন্স-ইনিশায়ালাইজেশন বা রেফারেন্স নীচে সংজ্ঞায়িত করা হয়েছে:

  • ...

  • অন্যথায়, যদি আরম্ভকারী তালিকার কোনও উপাদান থাকে না এবং টি একটি ডিফল্ট কনস্ট্রাক্টর সহ শ্রেণীর ধরণের হয় তবে অবজেক্টটি মান-আরম্ভ হয়।

থেকে ভিত্তেরিও রোমিও এর উত্তর


10

সিপ্রেফারেন্স থেকে :

সমষ্টিগত সূচনা সমষ্টিকে আরম্ভ করে। এটি তালিকা-সূচনার একটি ফর্ম।

একটি সামগ্রিক নিম্নলিখিত ধরণেরগুলির মধ্যে একটি:

[স্নিপ]

  • শ্রেণীর ধরণ [স্নিপ], এটি আছে

    • [স্নিপ] (বিভিন্ন স্ট্যান্ডার্ড সংস্করণের জন্য বিভিন্নতা রয়েছে)

    • কোনও ব্যবহারকারী-সরবরাহিত, উত্তরাধিকারসূত্রে বা স্পষ্টরূপে নির্মাণকারী (স্পষ্টভাবে ডিফল্ট বা মুছে ফেলা কনস্ট্রাক্টর অনুমোদিত)

    • [স্নিপ] (আরও নিয়ম রয়েছে, যা উভয় শ্রেণিতেই প্রযোজ্য)

এই সংজ্ঞাটি দেওয়া হয়েছে, fooএটি একটি সামগ্রিক, যদিও barএটি নয় (এটি ব্যবহারকারীর দ্বারা সরবরাহিত, অ-খেলাপি নির্ধারক রয়েছে)।

সুতরাং foo, T object {arg1, arg2, ...};সমষ্টিগত আরম্ভের জন্য সিনট্যাক্স।

সামগ্রিক সূচনাটির প্রভাবগুলি হ'ল:

  • [স্নিপ] (কিছু ক্ষেত্রে এই ক্ষেত্রে অপ্রাসঙ্গিক)

  • ইনিশিয়ালার ক্লজের সংখ্যা যদি সদস্যের সংখ্যার চেয়ে কম হয় বা ইনিশিয়ালাইজার তালিকাটি সম্পূর্ণ খালি থাকে, তবে বাকী সদস্যরা মান-আরম্ভ হয়

অতএব a.aমানটি আরম্ভ হয়, যার intঅর্থ শূন্য সূচনা হয়।

কারণ bar, T object {};অন্যদিকে হ'ল মান সূচনা (শ্রেণীর উদাহরণের, সদস্যদের মান আরম্ভ নয়)। যেহেতু এটি ডিফল্ট কনস্ট্রাক্টর সহ একটি শ্রেণিবদ্ধ, তাই ডিফল্ট কনস্ট্রাক্টরকে ডাকা হয়। আপনি যে ডিফল্ট নির্মাতাকে ডিফল্ট হিসাবে সংজ্ঞায়িত করেছেন তা সদস্যদের আরম্ভ করে (সদস্য ইনিশিয়ালিজার না থাকার কারণে), যা ক্ষেত্রে int(অ-স্থিতিশীল স্টোরেজ সহ) অনির্ধারিত b.bমান রেখে যায়।

এবং পড-প্রকারের জন্য, ডিফল্ট সূচনাটি শূন্য-আরম্ভ হয়।

না এটা ভুল।


পিএস আপনার পরীক্ষা এবং আপনার উপসংহার সম্পর্কে একটি শব্দ: আউটপুট শূন্য হয় তা দেখে অগত্যা যে চলকটি শূন্য ছিল তা আর নয়। শূন্য একটি আবর্জনা মূল্য জন্য নিখুঁত সম্ভব নম্বর।

তার জন্য আমি প্রোগ্রামটি চালিয়েছিলাম 5 ~ 6 বার পোস্ট করার আগে এবং এখন প্রায় 10 বার, একটি সর্বদা শূন্য। খ একটু পরিবর্তন হয়।

মানটি একাধিকবার ছিল এমনটি হওয়ার অর্থ এই নয় যে এটি আরম্ভ করা হয়েছিল।

আমি সেট (CMAKE_CXX_STANDARD 14) দিয়েও চেষ্টা করেছি। ফলাফল একই ছিল।

একাধিক সংকলক বিকল্পগুলির সাথে ফলাফলটি একইরকম হওয়ার অর্থ এই নয় যে ভেরিয়েবলটি আরম্ভ করা হয়েছে। (যদিও কিছু ক্ষেত্রে স্ট্যান্ডার্ড সংস্করণ পরিবর্তন করা শুরু করে কিনা তা পরিবর্তন করতে পারে)।

আমি কীভাবে কোনওভাবে আমার র‍্যামকে কিছুটা নাড়াতে পারি যাতে সেখানে যদি শূন্য থাকে তবে এটি এখন অন্য কিছু হওয়া উচিত

ননজারো প্রদর্শিত হওয়ার জন্য অবিচ্ছিন্ন মান মান তৈরি করার জন্য সি ++ তে কোনও গ্যারান্টিযুক্ত উপায় নেই।

কোনও পরিবর্তনশীল সূচনা হয় তা জানার একমাত্র উপায় হ'ল প্রোগ্রামের সাথে ভাষাটির নিয়মের তুলনা করা এবং তা যাচাই করে নিন যে বিধিগুলি এটি আরম্ভ করা হয়েছে ised এই ক্ষেত্রে a.aসত্যই আরম্ভ করা হয়।


"আপনি যে ডিফল্ট কনস্ট্রাক্টরটি ডিফল্ট হিসাবে সংজ্ঞায়িত করেছেন তা সদস্যদের আরম্ভ করে (সদস্য ইনিশিয়েশনার না থাকার কারণে), যা কোন ক্ষেত্রে অন্তহীন মান সহ ছেড়ে যায়।" -> আহ! "পড-প্রকারের জন্য, ডিফল্ট সূচনাটি শূন্য-আরম্ভ হয়" " আমি নাকি ভুল করছি?
ডক

2
@ জোয়েম্যালোন পিওডি প্রকারের ডিফল্ট সূচনা কোনও আরম্ভ নয়।
নাথান অলিভার

@ নাথান অলিভার, তারপরে আমি আরও বিভ্রান্ত হয়ে পড়েছি। তাহলে কীভাবে আসা শুরু aকরা হয়। আমি ভাবছিলাম aডিফল্ট ইনিশিয়ালাইজড এবং কোনও সদস্য পিওডের ডিফল্ট ইনিশিয়ালাইজেশন হ'ল শূন্য-ইনিশিয়ালাইজেশন। aতারপরে কি কেবল ভাগ্যক্রমে সর্বদা শূন্য হয়, যতই বার না আমি এই প্রোগ্রামটি চালাই।
হাঁস

@ জোয়েম্যালোন Then how come a is initialized.কারণ এটি প্রাথমিকভাবে মূল্যবান। I was thinking a is default initializedএইটা না.
এরেরিকা

3
@ জোয়েম্যালোন এটি সম্পর্কে চিন্তা করবেন না। আপনি সি ++ তে আরম্ভের বাইরে কোনও বই তৈরি করতে পারেন। আপনার উপর ইউটিউব সবচেয়ে (দেখিয়েছেন এটি কতটা খারাপ হিসেবে) হতাশ সঙ্গে আরম্ভের কয়েক ভিডিও নেই একটা সুযোগ CppCon করুন হচ্ছে youtube.com/watch?v=7DTlWPgX6zs
NathanOliver

0

মেহ, আমি আপনার সরবরাহিত স্নিপেটটি test.cppজিসিসি এবং ঝনঝন এবং একাধিক অনুকূলকরণ স্তরের মাধ্যমে চালানোর চেষ্টা করেছি :

steve@steve-pc /tmp> g++ -o test.gcc.O0 test.cpp
                                                                              [ 0s828 | Jan 27 01:16PM ]
steve@steve-pc /tmp> g++ -o test.gcc.O2 -O2 test.cpp
                                                                              [ 0s901 | Jan 27 01:16PM ]
steve@steve-pc /tmp> g++ -o test.gcc.Os -Os test.cpp
                                                                              [ 0s875 | Jan 27 01:16PM ]
steve@steve-pc /tmp> ./test.gcc.O0
0 32764                                                                       [ 0s004 | Jan 27 01:16PM ]
steve@steve-pc /tmp> ./test.gcc.O2
0 0                                                                           [ 0s004 | Jan 27 01:16PM ]
steve@steve-pc /tmp> ./test.gcc.Os
0 0                                                                           [ 0s003 | Jan 27 01:16PM ]
steve@steve-pc /tmp> clang++ -o test.clang.O0 test.cpp
                                                                              [ 1s089 | Jan 27 01:17PM ]
steve@steve-pc /tmp> clang++ -o test.clang.Os -Os test.cpp
                                                                              [ 1s058 | Jan 27 01:17PM ]
steve@steve-pc /tmp> clang++ -o test.clang.O2 -O2 test.cpp
                                                                              [ 1s109 | Jan 27 01:17PM ]
steve@steve-pc /tmp> ./test.clang.O0
0 274247888                                                                   [ 0s004 | Jan 27 01:17PM ]
steve@steve-pc /tmp> ./test.clang.Os
0 0                                                                           [ 0s004 | Jan 27 01:17PM ]
steve@steve-pc /tmp> ./test.clang.O2
0 0                                                                           [ 0s004 | Jan 27 01:17PM ]
steve@steve-pc /tmp> ./test.clang.O0
0 2127532240                                                                  [ 0s002 | Jan 27 01:18PM ]
steve@steve-pc /tmp> ./test.clang.O0
0 344211664                                                                   [ 0s004 | Jan 27 01:18PM ]
steve@steve-pc /tmp> ./test.clang.O0
0 1694408912                                                                  [ 0s004 | Jan 27 01:18PM ]

সুতরাং সেখানে এটি আকর্ষণীয় হয়ে ওঠে, এটি স্পষ্টভাবে ঝাঁকুনি O0 বিল্ডটি এলোমেলো সংখ্যাগুলি পড়তে দেখায়, সম্ভবত স্থানটি স্ট্যাক করে।

কী হচ্ছে তা দেখার জন্য আমি দ্রুত আমার আইডিএ চালু করেছিলাম:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  __int64 v3; // rax
  __int64 v4; // rax
  int result; // eax
  unsigned int v6; // [rsp+8h] [rbp-18h]
  unsigned int v7; // [rsp+10h] [rbp-10h]
  unsigned __int64 v8; // [rsp+18h] [rbp-8h]

  v8 = __readfsqword(0x28u); // alloca of 0x28
  v7 = 0; // this is foo a{}
  bar::bar((bar *)&v6); // this is bar b{}
  v3 = std::ostream::operator<<(&std::cout, v7); // this is clearly 0
  v4 = std::operator<<<std::char_traits<char>>(v3, 32LL); // 32 = 0x20 = ' '
  result = std::ostream::operator<<(v4, v6); // joined as cout << a.a << ' ' << b.b, so this is reading random values!!
  if ( __readfsqword(0x28u) == v8 ) // stack align check
    result = 0;
  return result;
}

এখন, কি bar::bar(bar *this)করে?

void __fastcall bar::bar(bar *this)
{
  ;
}

হুম, কিছুই না। আমাদের অ্যাসেম্বলি ব্যবহার করতে হবে:

.text:00000000000011D0                               ; __int64 __fastcall bar::bar(bar *__hidden this)
.text:00000000000011D0                                               public _ZN3barC2Ev
.text:00000000000011D0                               _ZN3barC2Ev     proc near               ; CODE XREF: main+20p
.text:00000000000011D0
.text:00000000000011D0                               var_8           = qword ptr -8
.text:00000000000011D0
.text:00000000000011D0                               ; __unwind {
.text:00000000000011D0 55                                            push    rbp
.text:00000000000011D1 48 89 E5                                      mov     rbp, rsp
.text:00000000000011D4 48 89 7D F8                                   mov     [rbp+var_8], rdi
.text:00000000000011D8 5D                                            pop     rbp
.text:00000000000011D9 C3                                            retn
.text:00000000000011D9                               ; } // starts at 11D0
.text:00000000000011D9                               _ZN3barC2Ev     endp

সুতরাং হ্যাঁ, এটি ঠিক, কিছুই নয়, কনস্ট্রাক্টর মূলত যা করে this = this। তবে আমরা জানি যে এটি আসলে এলোমেলোভাবে স্টোরের ঠিকানাগুলি এলোমেলো করে লোড করছে এবং এটি মুদ্রণ করবে।

আমরা যদি দুটি স্ট্রাক্টের জন্য স্পষ্টভাবে মান সরবরাহ করি তবে কী হবে?

#include <iostream>

struct foo {
    foo() = default;
    int a;
};

struct bar {
    bar();
    int b;
};

bar::bar() = default;

int main() {
    foo a{0};
    bar b{0};
    std::cout << a.a << ' ' << b.b;
}

ঝাঁকুনি দাও, উফস:

steve@steve-pc /tmp> clang++ -o test.clang.O0 test.cpp
test.cpp:17:9: error: no matching constructor for initialization of 'bar'
    bar b{0};
        ^~~~
test.cpp:8:8: note: candidate constructor (the implicit copy constructor) not viable: no known conversion
      from 'int' to 'const bar' for 1st argument
struct bar {
       ^
test.cpp:8:8: note: candidate constructor (the implicit move constructor) not viable: no known conversion
      from 'int' to 'bar' for 1st argument
struct bar {
       ^
test.cpp:13:6: note: candidate constructor not viable: requires 0 arguments, but 1 was provided
bar::bar() = default;
     ^
1 error generated.
                                                                              [ 0s930 | Jan 27 01:35PM ]

জি ++ এর সাথে একই রকম ভাগ্য:

steve@steve-pc /tmp> g++ test.cpp
test.cpp: In function int main()’:
test.cpp:17:12: error: no matching function for call to bar::bar(<brace-enclosed initializer list>)’
     bar b{0};
            ^
test.cpp:8:8: note: candidate: bar::bar()’
 struct bar {
        ^~~
test.cpp:8:8: note:   candidate expects 0 arguments, 1 provided
test.cpp:8:8: note: candidate: constexpr bar::bar(const bar&)’
test.cpp:8:8: note:   no known conversion for argument 1 from int to const bar&’
test.cpp:8:8: note: candidate: constexpr bar::bar(bar&&)’
test.cpp:8:8: note:   no known conversion for argument 1 from int to bar&&’
                                                                              [ 0s718 | Jan 27 01:35PM ]

সুতরাং এর অর্থ এটি কার্যকরভাবে সরাসরি সূচনা bar b(0), সমষ্টিগত আরম্ভ নয়।

এটি সম্ভবত কারণ আপনি যদি একটি সুস্পষ্ট নির্মাতা বাস্তবায়ন সরবরাহ না করেন তবে এটি সম্ভবত বাহ্যিক প্রতীক হতে পারে, উদাহরণস্বরূপ:

bar::bar() {
  this.b = 1337; // whoa
}

সংকলকটি কোনও অপ-অপ্টিমাইজড পর্যায়ে কোনও অন-অপশন / একটি ইনলাইন কল হিসাবে এটি কমাতে যথেষ্ট স্মার্ট নয়।

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