সি ++ এ নতুন কীওয়ার্ডটি কখন ব্যবহার করা উচিত?


272

আমি অল্প সময়ের জন্য সি ++ ব্যবহার করছি এবং আমি নতুন কীওয়ার্ডটি নিয়ে ভাবছিলাম । কেবল, আমি এটি ব্যবহার করা উচিত, না?

1) নতুন কীওয়ার্ড সহ ...

MyClass* myClass = new MyClass();
myClass->MyField = "Hello world!";

2) নতুন কীওয়ার্ড ব্যতীত ...

MyClass myClass;
myClass.MyField = "Hello world!";

বাস্তবায়নের দৃষ্টিকোণ থেকে, তারা এটিকে আলাদা বলে মনে হয় না (তবে আমি তারা নিশ্চিত যে তারা) ... তবে, আমার প্রাথমিক ভাষাটি সি #, এবং অবশ্যই 1 ম পদ্ধতিটি আমি ব্যবহার করছি।

অসুবিধা বলে মনে হচ্ছে যে পদ্ধতিটি 1 স্ট্যান্ড সি ++ ক্লাসে ব্যবহার করা আরও কঠিন er

আমার কোন পদ্ধতিটি ব্যবহার করা উচিত?

আপডেট 1:

আমি সম্প্রতি হ্যাপ মেমোরির জন্য নতুন কীওয়ার্ডটি (বা ফ্রি স্টোর ) একটি বড় অ্যারের জন্য ব্যবহার করেছি যা সুযোগের বাইরে চলেছে (অর্থাত্ কোনও ফাংশন থেকে ফিরে আসছে)। আমি স্ট্যাকটি ব্যবহার করার আগে যেখানে অর্ধেক উপাদানগুলি সুযোগের বাইরে দূষিত হয়ে পড়েছিল, গাদা ব্যবহারে স্যুইচ করে নিশ্চিত করেছিল যে উপাদানগুলি কৌশলযুক্ত ছিল। হ্যাঁ!

আপডেট 2:

আমার এক বন্ধু আমাকে সম্প্রতি বলেছিল newকীওয়ার্ডটি ব্যবহারের জন্য একটি সহজ নিয়ম ; প্রতিবার আপনি টাইপ করুন new, টাইপ করুন delete

Foobar *foobar = new Foobar();
delete foobar; // TODO: Move this to the right place.

এটি মেমোরি ফাঁস রোধ করতে সহায়তা করে, কারণ আপনি সর্বদা মুছে ফেলা অন্য কোথাও রাখতে হবে (যেমন আপনি এটি কাটাতে এবং এটি কোনও ডেস্ট্রাক্টর বা অন্যথায় অন্য কোনও জায়গায় আটকে দিতে হবে)।


6
সংক্ষিপ্ত উত্তরটি হ'ল, আপনি যখন এটির সাথে দূরে থাকতে পারেন তখন সংক্ষিপ্ত সংস্করণটি ব্যবহার করুন। :)
জাল্ফ

11
সর্বদা সম্পর্কিত মোছার চেয়ে ভাল কৌশল - এসটিএল পাত্রে এবং স্মার্ট পয়েন্টারগুলি std::vectorএবং এর মতো ব্যবহার করুন std::shared_ptr। এগুলি আপনার জন্য newএবং আপনার deleteজন্য কলগুলি মোড়ক করে রাখে , তাই আপনার মেমরি ফাঁস হওয়ার সম্ভাবনা কম less নিজেকে জিজ্ঞাসা করুন, উদাহরণস্বরূপ: আপনি কি সর্বদা deleteএকটি ব্যতিক্রম নিক্ষেপ করা যেতে পারে সর্বত্র একটি অনুরূপ করা মনে রাখবেন ? নির্বাণ deleteহাতে গুলি কঠিন চেয়ে আপনার মনে হতে পারে হয়।
অ্যাশলেব্রাইন

@nbolton লিখেছেন: আপডেট 1 - সি সম্পর্কে ++, সুন্দর জিনিস এক এটি আপনি, স্ট্যাক ব্যবহারকারী বর্ণিত প্রকারভেদ সঞ্চয় করতে যেহেতু C # এর মত আবর্জনা সংগ্রহ ভাষাগুলির দেয় বল আপনি ডেটা জমা করতে গাদাগাদা হ্রাস স্ট্যাক ডেটা সঞ্চয় করার চেয়ে আরও বেশি সম্পদের উপর ডেটা সঞ্চয় করার , এইভাবে আপনি ব্যবহার করা উচিৎ স্ট্যাক থেকে গাদা ছাড়া যখন আপনার UDT তার ডেটা জমা করতে মেমরির একটি বৃহৎ পরিমাণ প্রয়োজন। (এর অর্থ হ'ল বস্তুগুলি ডিফল্টরূপে মান দ্বারা পাস হয়)। আপনার সমস্যার আরও ভাল সমাধান হ'ল অ্যারেটিকে রেফারেন্স দ্বারা ফাংশনটিতে স্থান দেওয়া হবে
চার্লস অ্যাডিস

উত্তর:


303

পদ্ধতি 1 (ব্যবহার করে new)

  • ফ্রি স্টোরটিতে অবজেক্টের জন্য মেমরি বরাদ্দ করে (এটি প্রায়শই হিপ হিসাবে একই জিনিস হয় )
  • আপনাকে deleteপরে স্পষ্টভাবে আপনার অবজেক্টের প্রয়োজন । (আপনি যদি এটি মুছেন না, আপনি একটি মেমরি ফাঁস তৈরি করতে পারেন)
  • মেমরি বরাদ্দ থাকে আপনি deleteএটি না করা পর্যন্ত । (অর্থাত্ আপনি returnব্যবহার করে তৈরি করেছেন এমন কোনও বস্তু new)
  • প্রশ্নটির উদাহরণ মেমরি ফাঁস করবে যদি না পয়েন্টারটি deleteডি হয়; কোনও নিয়ন্ত্রণের পথ নেওয়া বা ব্যতিক্রম ছুঁড়ে ফেলা হোক না কেন এবং এটি সর্বদা মুছে ফেলা উচিত

পদ্ধতি 2 (ব্যবহার করছে না new)

  • স্ট্যাকের জন্য বস্তুর জন্য মেমরি বরাদ্দ করে (যেখানে সমস্ত স্থানীয় ভেরিয়েবলগুলি যায়) স্ট্যাকের জন্য সাধারণত কম মেমরি পাওয়া যায়; যদি আপনি অনেকগুলি বস্তু বরাদ্দ করেন তবে আপনার স্ট্যাকের ওভারফ্লো ঝুঁকিপূর্ণ।
  • আপনার deleteপরে এটির প্রয়োজন হবে না ।
  • সুযোগের বাইরে গেলে মেমরির আর বরাদ্দ থাকে না। (অর্থাত্ returnস্ট্যাকের কোনও বস্তুর প্রতি আপনার পয়েন্টার দেওয়া উচিত নয় )

যতদূর কোনটি ব্যবহার করা উচিত; উপরের সীমাবদ্ধতাগুলি দেখিয়ে আপনি সেই পদ্ধতিটি বেছে নিন যা আপনার পক্ষে সবচেয়ে ভাল কাজ করে।

কিছু সহজ ক্ষেত্রে:

  • আপনি যদি কল করার বিষয়ে চিন্তা করতে না চান delete, (এবং মেমরি ফাঁস হওয়ার সম্ভাবনা ) আপনার ব্যবহার করা উচিত নয় new
  • আপনি যদি কোনও ফাংশন থেকে আপনার অবজেক্টে কোনও পয়েন্টার ফিরিয়ে দিতে চান তবে আপনাকে অবশ্যই ব্যবহার করতে হবে new

4
একটি নিটপিক - আমি বিশ্বাস করি যে নতুন অপারেটর "ফ্রি স্টোর" থেকে মেমরি বরাদ্দ করে, যখন ম্যালোক "হিপ" থেকে বরাদ্দ করে। এগুলি একই জিনিস হওয়ার গ্যারান্টিযুক্ত নয়, যদিও বাস্তবে এটি সাধারণত হয়। Getw.ca/gotw/009.htm দেখুন ।
ফ্রেড লারসন

4
আমি মনে করি আপনার উত্তরটি আরও পরিষ্কার হতে পারে যার উপর ব্যবহার করা উচিত। (সময় 99%, পছন্দ সহজ পদ্ধতি 2, একটি লেফাফা বস্তুর যা নতুন কল ব্যবহার করুন কন্সট্রাকটর / বিনাশকারী ইন / মুছে দিন।)
jalf

4
@ জাল্ফ: পদ্ধতি 2 হ'ল নতুনটি ব্যবহার করে না: - / যে কোনও ক্ষেত্রে আপনার কোড কোড অনেক সহজ হবে (উদাহরণস্বরূপ ত্রুটির ঘটনাগুলি পরিচালনা করে) পদ্ধতি 2 (নতুনটি ছাড়া একটি) ব্যবহার করে
ড্যানিয়েল লেচেমিন্যান্ট

আরেকটি নিতপিক ... আপনার আরও স্পষ্ট করে দেওয়া উচিত যে নিকের প্রথম উদাহরণটি স্মৃতি ফাঁস করে, যদিও তার দ্বিতীয়টি এমনকি ব্যতিক্রমতার পরেও নয়।
আরাফ্যাঙ্গিয়ন

4
@ ফ্রেড, আরাফ্যাঙ্গিয়ন: আপনার অন্তর্দৃষ্টি জন্য ধন্যবাদ; আমি আপনার মন্তব্যগুলিকে উত্তরে অন্তর্ভুক্ত করেছি।
ড্যানিয়েল লেচেমিন্যান্ট

118

দুজনের মধ্যে একটি গুরুত্বপূর্ণ পার্থক্য রয়েছে।

সবকিছু বরাদ্দ না newঅনেক C # এর মান ধরনের মত আচরণ (এবং মানুষ প্রায়ই বলবো যে, এসব বস্তু স্ট্যাক, যা সম্ভবত সবচেয়ে সাধারণ / সুস্পষ্ট ক্ষেত্রে দেখা যায় বরাদ্দ করা হয়, তবে সব সময় নয় সত্য। আরো অবিকল, বস্তু বরাদ্দ ব্যবহার না করেই newআছে স্বয়ংক্রিয় স্টোরেজ সময়সীমার সাথে বরাদ্দকৃত সমস্ত newকিছুই গাদাতে বরাদ্দ করা হয়, এবং এর পয়েন্টারটি ফিরে আসে, ঠিক সি # তে রেফারেন্সের ধরণের মতো।

স্ট্যাকের জন্য বরাদ্দকৃত যেকোন কিছুতে একটি ধ্রুব আকার থাকতে হবে, সংকলন সময়ে নির্ধারিত (সংকলকটিকে স্ট্যাক পয়েন্টারটি সঠিকভাবে সেট করতে হবে, বা যদি বস্তু অন্য শ্রেণীর সদস্য হয়, তবে এটি অন্য শ্রেণীর আকার সামঞ্জস্য করতে হবে) । এজন্য সি # তে অ্যারেগুলি রেফারেন্স ধরণের। সেগুলি হতে হবে, কারণ রেফারেন্সের ধরণের সাথে আমরা রানটাইমে সিদ্ধান্ত নিতে পারি যে কত মেমরি চাইবে। এবং একই এখানে প্রযোজ্য। কেবল ধ্রুব আকারের অ্যারেগুলি (একটি আকার যা সংকলন সময়ে নির্ধারণ করা যায়) স্বয়ংক্রিয় স্টোরেজ সময়কাল (স্ট্যাকের) দিয়ে বরাদ্দ করা যেতে পারে। গতিবেগের আকারের অ্যারেগুলি কল করে, গাদাতে বরাদ্দ করতে হবে new

(এবং সেখানে সি # এর সাথে কোনও মিল রয়েছে)

এখন, স্ট্যাকের জন্য বরাদ্দকৃত কোনও কিছুর "স্বয়ংক্রিয়" স্টোরেজ সময়কাল রয়েছে (আপনি আসলে কোনও ভেরিয়েবল হিসাবে ঘোষণা করতে পারেন auto, তবে অন্য কোনও স্টোরেজ প্রকার নির্দিষ্ট না করা থাকলে কীওয়ার্ডটি বাস্তবে ব্যবহার করা হয়নি, তবে এটি এটিই এখানে থেকে আসে)

স্বয়ংক্রিয় স্টোরেজ সময়কালের অর্থ হ'ল ঠিক কী মনে হচ্ছে, ভেরিয়েবলের সময়কাল স্বয়ংক্রিয়ভাবে পরিচালনা করা হয়। বিপরীতে, গাদাতে বরাদ্দকৃত যেকোন কিছুই আপনাকে ম্যানুয়ালি মুছে ফেলতে হবে। এখানে একটি উদাহরণ:

void foo() {
  bar b;
  bar* b2 = new bar();
}

এই ফাংশনটি বিবেচনার জন্য তিনটি মান তৈরি করে:

লাইন 1 এ, এটি স্ট্যাকের ( bধরণের barস্বয়ংক্রিয় সময়কাল) ধরণের পরিবর্তনশীল ঘোষণা করে ।

লাইন 2 এ, এটি স্ট্যাকের একটি barপয়েন্টার ঘোষণা করে b2(স্বয়ংক্রিয় সময়কাল), এবং নতুনকে কল barকরে, স্তূপে একটি অবজেক্ট বরাদ্দ করে। (গতিশীল সময়কাল)

যখন ফাংশনটি ফিরে আসবে, নিম্নলিখিতটি ঘটবে: প্রথমে, b2সুযোগের বাইরে চলে যায় (ধ্বংসের ক্রমটি সর্বদা নির্মাণের ক্রমের বিপরীতে থাকে)। তবে b2এটি কেবল একটি পয়েন্টার, তাই কিছুই হয় না, এটি যে স্মৃতি ধারণ করে তা কেবল মুক্তি দেওয়া হয়। এবং গুরুত্বপূর্ণ বিষয়, এটি যে স্মৃতিটি ইঙ্গিত করে ( barগাদা উপরের উদাহরণটি) তা স্পর্শ করে না। কেবলমাত্র পয়েন্টারটি মুক্ত হয়, কারণ কেবলমাত্র পয়েন্টারের স্বয়ংক্রিয় সময়কাল ছিল। দ্বিতীয়ত, bসুযোগের বাইরে চলে যায়, সুতরাং এটির স্বয়ংক্রিয় সময়কাল হওয়ায় এর ডেস্ট্রাক্টরকে ডাকা হয় এবং স্মৃতি মুক্ত হয়।

এবং barগাদা নেভিগেশন উদাহরণ? এটা সম্ভবত এখনও আছে। কেউ এটিকে মুছতে বিরক্ত করেননি, তাই আমরা স্মৃতি ফাঁস করেছি।

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

এবং এটি বেশিরভাগ সি ++ কোড কীভাবে কাজ করে ঠিক তা ঠিক। std::vectorউদাহরণস্বরূপ স্ট্যান্ডার্ড লাইব্রেরির দিকে তাকান । এটি সাধারণত স্ট্যাকের জন্য বরাদ্দ করা হয়, তবে গতিশীল আকার এবং আকার পরিবর্তন করা যেতে পারে। এবং এটি অভ্যন্তরীণভাবে প্রয়োজনীয়ভাবে গাদাতে মেমরি বরাদ্দ করে এটি করে। শ্রেণীর ব্যবহারকারী এটি কখনই দেখে না, সুতরাং মেমরি ফাঁস হওয়ার বা আপনার বরাদ্দকৃত জিনিসগুলি পরিষ্কার করতে ভুলে যাওয়ার কোনও সম্ভাবনা নেই।

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

একটি সাধারণ নিয়ম হিসাবে, আপনার উচ্চ স্তরের কোড থেকে সরাসরি নতুন / মুছুন কখনই ব্যবহার করবেন না। সর্বদা এটিকে এমন একটি ক্লাসে মুড়ে দিন যা আপনার জন্য স্মৃতি পরিচালনা করতে পারে এবং যা নিশ্চিত করে যে এটি আবার মুক্তি পেয়েছে। (হ্যাঁ, এই নিয়মের ব্যতিক্রম হতে পারে। বিশেষ করে, স্মার্ট পয়েন্টার কল করার প্রয়োজন newসরাসরি, এবং তার কন্সট্রাকটর, যা উপর এবং নিশ্চিত লাগে পয়েন্টার পাস deleteসঠিকভাবে বলা হয়। কিন্তু এই এখনও একটি চলতি খুবই গুরুত্বপূর্ণ নিয়ম )


2
"নতুনের সাথে বরাদ্দ না করা সমস্ত কিছু স্ট্যাকের উপরে স্থাপন করা হয়" আমি যে সিস্টেমে কাজ করেছি সেগুলিতে নয় ... সাধারণত আন্তঃবিজ্ঞানযুক্ত (এবং অবিচ্ছিন্ন) গ্লোবাল (স্ট্যাটিক) ডেটা তাদের নিজস্ব বিভাগগুলিতে স্থাপন করা হয়। উদাহরণস্বরূপ, .ডাটা, .বিএস, ইত্যাদি ... লিঙ্কার সেগমেন্ট। পেডেন্টিক, আমি জানি ...
ড্যান

অবশ্যই, আপনি ঠিক বলেছেন। আমি সত্যিই স্থির ডেটা নিয়ে ভাবছিলাম না। আমার খারাপ অবশ্যই। :)
জলফ

2
স্ট্যাকের জন্য বরাদ্দকৃত কোনও কিছুর ধ্রুব আকার থাকতে হবে?
ব্যবহারকারী541686

এটি সবসময় হয় না , এটিকে বিঘ্নিত করার কয়েকটি উপায় রয়েছে তবে সাধারণ ক্ষেত্রে এটি হয়, কারণ এটি স্ট্যাকের উপর রয়েছে। যদি এটি স্ট্যাকের শীর্ষে থাকে, তবে এটির আকার পরিবর্তন করা সম্ভব হতে পারে তবে একবার এর উপরে অন্য কিছু চাপ দেওয়া হলে এটি "দেওয়াল ইন" থাকে, উভয় পাশের বস্তু দ্বারা ঘিরে থাকে, সুতরাং এটি সত্যিই আকার পরিবর্তন করতে পারে না । হ্যাঁ, বলার অপেক্ষা রাখে না এটা সবসময় যে হয়েছে একটি নির্দিষ্ট আকার একটা সরলীকৃত একটি বিট আছে, কিন্তু এটা মৌলিক ধারণা conveys (এবং আমি সি ফাংশন যা আপনাকে স্ট্যাকের বরাদ্দ সাথেও সৃজনশীল হতে দেওয়া সঙ্গে সম্পর্কে তালগোল পাকানো না করার পরামর্শ দিচ্ছি)
jalf

14

আমার কোন পদ্ধতিটি ব্যবহার করা উচিত?

এটি প্রায়শই আপনার টাইপিং পছন্দগুলি দ্বারা নয় তবে প্রসঙ্গ দ্বারা নির্ধারিত হয়। আপনাকে যদি কয়েকটি স্ট্যাক জুড়ে অবজেক্টটি রাখা দরকার হয় বা স্ট্যাকের পক্ষে এটি খুব ভারী হয় তবে আপনি এটিকে ফ্রি স্টোরে বরাদ্দ করেন। এছাড়াও, যেহেতু আপনি কোনও বিষয় বরাদ্দ করছেন, তাই আপনি স্মৃতি মুক্ত করার জন্যও দায়ী। deleteঅপারেটর দেখুন ।

ফ্রি-দোকান ব্যবস্থাপনা মানুষ ব্যবহারের বোঝা আরাম ভালো জিনিস আবিষ্কার করেছেন auto_ptrএবং unique_ptr। আমি আপনাকে দৃ strongly়ভাবে সুপারিশ করছি এগুলি একবার দেখুন। এমনকি তারা আপনার টাইপিং সমস্যাগুলিতে সহায়তা করতে পারে ;-)


10

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

যেমনটি অন্যেরা বলেছেন, আপনার নতুনটির প্রয়োজন যখন আপনার বস্তুটি ফাংশন বা অবজেক্টের বাইরে থাকতে হবে তখন অবজেক্টটি সত্যই বড় বা যখন আপনি যখন সঙ্কলনের সময় কোনও অ্যারের আকার জানেন না তখন।

এছাড়াও, মুছে ফেলা ব্যবহার এড়াতে চেষ্টা করুন। পরিবর্তে আপনার নতুনটিকে স্মার্ট পয়েন্টারে মুড়ে দিন। আপনার জন্য স্মার্ট পয়েন্টার কলটি মোছা দিন।

কিছু ক্ষেত্রে রয়েছে যেখানে স্মার্ট পয়েন্টারটি স্মার্ট নয়। এসটিএল কনটেইনারের মধ্যে কখনও স্টাড :: অটো_পিটার <> সংরক্ষণ করবেন না। ধারকের ভিতরে অনুলিপি করার কারণে এটি পয়েন্টারটি খুব শীঘ্রই মুছে ফেলবে। আর একটি ক্ষেত্রে যখন আপনার কাছে বস্তুগুলিতে পয়েন্টারগুলির একটি সত্যই বড় এসটিএল ধারক থাকে। উত্সাহ: শেয়ারড_পিটার <> এর রেফারেন্সটিকে উপরে এবং নীচে গণনা করায় গতি ওভারহেডের এক টন থাকবে। সেক্ষেত্রে যাওয়ার সর্বোত্তম উপায় হ'ল এসটিএল কনটেইনারটিকে অন্য কোনও বস্তুর মধ্যে স্থাপন করা এবং সেই অবজেক্টটিকে এমন একটি ডেস্ট্রাক্টর দেওয়া যা ধারকটির প্রতিটি পয়েন্টারে ডিলিট কল করবে।


10

সংক্ষিপ্ত উত্তরটি হ'ল: আপনি যদি সি ++ তে শিক্ষানবিস হন তবে আপনার বা নিজেকে কখনও ব্যবহার করা উচিত নয়newdelete

পরিবর্তে, আপনার স্মার্ট পয়েন্টার ব্যবহার করা উচিত যেমন std::unique_ptrএবং std::make_unique(বা কম প্রায়ই std::shared_ptrএবং std::make_shared)। এইভাবে, আপনাকে মেমরি ফাঁস সম্পর্কে প্রায় ততটা চিন্তা করতে হবে না। এমনকি আপনি আরও উন্নত হলেও সর্বোত্তম অনুশীলনটি হ'ল আপনি যে কাস্টম পদ্ধতিটি ব্যবহার করছেন তা newএবং deleteএকটি ছোট শ্রেণিতে (যেমন একটি কাস্টম স্মার্ট পয়েন্টার) যা কেবলমাত্র জীবনচক্র সংক্রান্ত বিষয়গুলিকে আপত্তি জানাতে উত্সর্গীকৃত হয় তা enc

অবশ্যই, পর্দার আড়ালে, এই স্মার্ট পয়েন্টারগুলি এখনও গতিশীল বরাদ্দ এবং ডিএলোকেশন সম্পাদন করছে, সুতরাং তাদের ব্যবহার করা কোডটিতে এখনও সম্পর্কিত রানটাইম ওভারহেড থাকতে পারে। এখানে অন্যান্য উত্তরগুলি এই বিষয়গুলি কভার করেছে এবং কীভাবে কখন স্ট্যাকের উপর বস্তু তৈরি করা বা কোনও বস্তুর প্রত্যক্ষ সদস্য হিসাবে তাদেরকে অন্তর্ভুক্ত করে স্মার্ট পয়েন্টার ব্যবহার করতে হবে সে বিষয়ে কীভাবে নকশা সিদ্ধান্ত নেওয়ার পক্ষে যথেষ্ট তা যথেষ্ট যে আমি এগুলি পুনরুক্ত করব না। তবে আমার নির্বাহী সংক্ষিপ্তসারটি হ'ল: স্মার্ট পয়েন্টার বা গতিশীল বরাদ্দ ব্যবহার করবেন না যতক্ষণ না কোনও কিছু আপনাকে জোর করে।


সময়ের সাথে সাথে উত্তর কীভাবে পরিবর্তিত হতে পারে তা দেখতে আকর্ষণীয়;)
ওল্ফ


2

এর সহজ উত্তর হ্যাঁ - নতুন () স্তূপে একটি অবজেক্ট তৈরি করে (দুর্ভাগ্যজনক পার্শ্ব প্রতিক্রিয়া সহ যা আপনাকে তার জীবনকাল পরিচালনা করতে হবে (স্পষ্টভাবে এটি মুছুন বলে ডাকে)), যখন দ্বিতীয় রূপটি স্ট্যাকের মধ্যে একটি বস্তু তৈরি করে সুযোগের বাইরে চলে গেলে সুযোগ এবং সেই বস্তুটি ধ্বংস হয়ে যাবে।


1

যদি আপনার ভেরিয়েবলটি কেবল একটি একক ফাংশনের প্রসঙ্গে ব্যবহার করা হয় তবে আপনি স্ট্যাক ভেরিয়েবল, অর্থাত্ বিকল্প 2 ব্যবহার করা ভাল others স্বয়ংক্রিয়ভাবে ধ্বংস। এছাড়াও, গাদাতে একটি ভেরিয়েবল বরাদ্দ / নির্ধারণ করা তুলনা করে ধীরে ধীরে। যদি আপনার ফাংশনটি প্রায়শই পর্যাপ্ত পরিমাণে বলা হয় তবে আপনি স্ট্যাপ ভেরিয়েবল বনাম হিপ ভেরিয়েবল ব্যবহার করলে আপনি দুর্দান্ত পারফরম্যান্সের উন্নতি দেখতে পাবেন।

এটি বলেছিল, বেশ কয়েকটি সুস্পষ্ট দৃষ্টান্ত রয়েছে যেখানে স্ট্যাক ভেরিয়েবলগুলি অপর্যাপ্ত।

যদি স্ট্যাক ভেরিয়েবলের একটি বড় মেমরির পদচিহ্ন থাকে তবে আপনি স্ট্যাকটি উপচে পড়ার ঝুঁকিটি চালান। ডিফল্টরূপে, প্রতিটি থ্রেডের স্ট্যাকের আকার উইন্ডোজটিতে 1 এমবি । এটি অসম্ভাব্য যে আপনি একটি স্ট্যাক ভেরিয়েবল তৈরি করুন যা 1 এমবি আকারের, তবে আপনাকে মনে রাখতে হবে যে স্ট্যাকের ব্যবহারটি ক্রমযুক্ত। যদি আপনার ফাংশন এমন কোনও ফাংশনকে কল করে যা অন্য ফাংশনকে কল করে যা অন্য ফাংশনকে কল করে ..., এই সমস্ত কার্যক্রমে স্ট্যাক ভেরিয়েবল একই স্ট্যাকের স্থান গ্রহণ করে। পুনরাবৃত্তির ক্রিয়াগুলি কত গভীর হয় তার উপর নির্ভর করে দ্রুত এই সমস্যাটির মধ্যে চলে। যদি এটি কোনও সমস্যা হয় তবে আপনি নতুন অপারেটর (প্রস্তাবিত) ব্যবহার করে স্ট্যাকের আকার বাড়াতে পারেন (প্রস্তাবিত নয়) the

অন্যটি, সম্ভবত সম্ভাব্য শর্তটি হল আপনার ভেরিয়েবলটি আপনার ফাংশনের ক্ষেত্রের বাইরে "লাইভ" হওয়া দরকার। এই ক্ষেত্রে, আপনি গাদা উপর পরিবর্তনশীল বরাদ্দ করতে চাই যাতে এটি কোনও প্রদত্ত ফাংশনের সুযোগের বাইরে পৌঁছানো যায়।


1

আপনি কি কোনও ফাংশন থেকে মাইক্লাস পাস করছেন, বা or ফাংশনের বাইরে এটির উপস্থিতি আশা করছেন? অন্য কিছু যেমন বলেছেন, আপনি যখন গাদাতে বরাদ্দ দিচ্ছেন না তখন এটি সমস্ত সুযোগের বিষয়। আপনি যখন ফাংশনটি ছেড়ে যান, এটি চলে যায় (শেষ পর্যন্ত)। নতুনদের দ্বারা ক্লাসিক ভুলগুলির মধ্যে একটি হ'ল কোনও ফাংশনে কিছু শ্রেণির স্থানীয় অবজেক্ট তৈরি করা এবং গাদাতে বরাদ্দ না দিয়ে এটিকে ফিরিয়ে দেওয়ার প্রচেষ্টা। আমি আমার আগের দিনগুলিতে সি ++ করে এই ধরণের জিনিসটি ডিবাগ করার কথা মনে করতে পারি।


0

দ্বিতীয় পদ্ধতিটি স্ট্যাকের উপর উদাহরণ তৈরি করে, যেমন ঘোষিত কিছু intএবং ফাংশনে উত্তীর্ণ হওয়া পরামিতিগুলির তালিকা।

প্রথম পদ্ধতিটি স্ট্যাকের উপরে একটি পয়েন্টার রাখার জায়গা তৈরি করে, যা আপনি মেমরির স্থানে সেট MyClassকরেছেন যেখানে গাদা - বা ফ্রি স্টোরে নতুন বরাদ্দ করা হয়েছে।

প্রথম পদ্ধতির জন্যও আপনি যেটি deleteতৈরি করেন তা আপনার প্রয়োজন হয় new, অন্যদিকে দ্বিতীয় পদ্ধতিতে ক্লাসটি সুযোগের বাইরে পড়লে স্বয়ংক্রিয়ভাবে ধ্বংস হয়ে যায় এবং মুক্ত হয় (পরবর্তী বন্ধনী বন্ধনী সাধারণত:)।


-1

সংক্ষিপ্ত উত্তর হ্যাঁ "নতুন" কীওয়ার্ডটি অবিশ্বাস্যরূপে গুরুত্বপূর্ণ কারণ আপনি যখন এটি ব্যবহার করবেন তখন অবজেক্টের ডেটা স্ট্যাকের বিপরীতে গাদাতে সংরক্ষণ করা হয়, যা সবচেয়ে গুরুত্বপূর্ণ!

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