সি ++ স্ট্রাক্টের সদস্যরা কি ডিফল্টরূপে 0 থেকে আরম্ভ করা হয়?


200

আমার এটি আছে struct:

struct Snapshot
{
    double x; 
    int y;
};

আমি চাই xএবং চাই y0। তারা ডিফল্ট হিসাবে 0 হবে বা আমার কি করতে হবে:

Snapshot s = {0,0};

কাঠামো শূন্য করার অন্যান্য উপায়গুলি কী কী?


একটি স্ট্যান্ড :: মানচিত্র <> ব্যবহার করুন এবং কীটি উপস্থিত না থাকলে 0 ফিরে আসুন।
জনি

উত্তর:


263

আপনি স্ট্রাক্টটি আরম্ভ না করলে এগুলি নাল নয়।

Snapshot s; // receives no initialization
Snapshot s = {}; // value initializes all members

দ্বিতীয়টি সমস্ত সদস্যকে শূন্য করে দেবে, প্রথমটি তাদের অনির্ধারিত মানগুলিতে ফেলে দেয়। নোট করুন যে এটি পুনরাবৃত্ত হয়:

struct Parent { Snapshot s; };
Parent p; // receives no initialization
Parent p = {}; // value initializes all members

দ্বিতীয়টি p.s.{x,y}শূন্য করবে । আপনি যদি আপনার স্ট্রাক্টে কনস্ট্রাক্টর পেয়ে থাকেন তবে আপনি এই সামগ্রিক আরম্ভকারী তালিকাটি ব্যবহার করতে পারবেন না। যদি এটি হয় তবে আপনাকে সেই নির্মাতাদের যথাযথ সূচনা যোগ করতে হবে

struct Snapshot {
    int x;
    double y;
    Snapshot():x(0),y(0) { }
    // other ctors / functions...
};

X এবং y উভয়কেই আরম্ভ করবে ০. দ্রষ্টব্য যে আপনি x(), y()তাদের প্রকারের বিষয়টিকে উপেক্ষা করে আরম্ভ করার জন্য ব্যবহার করতে পারেন : এরপরে এটির আরম্ভকরণের মান হয় এবং সাধারণত একটি প্রাথমিক প্রাথমিক মান পাওয়া যায় (ডাবল জন্য ০.০, ডাবল জন্য ০.০, ব্যবহারকারীকে সংজ্ঞায়িত করার জন্য ডিফল্ট কনস্ট্রাক্টর বলা হয়) প্রকারভেদে ব্যবহারকারী ঘোষিত কনস্ট্রাক্টর রয়েছে ...)। এটি গুরুত্বপূর্ণ যদি আপনার স্ট্রাক্ট একটি টেম্পলেট হয় especially


1
এটি আমার সংকলকটিতে প্রচুর সতর্কতা তৈরি করে।
রিভার-ক্লেয়ার উইলিয়ামসন

1
রজার: ইনিশিয়ালাইজারে নামকৃত স্ট্রাক্টটি ব্যবহার করার চেষ্টা করুন, এটি আমিই করি এবং ভিসি ২০১২ তে আমি কোনও সতর্কতা পাই না: স্ন্যাপশট s = স্ন্যাপশট ();
কিট 10

@ জোহানেস স্কাউব - লিটব Snapshot s = {};পিওডি সদস্যবিহীন সদস্যদের জন্য কাজ করবেন (তাদের শূন্য করার জন্য)?
অনথ্রোকস

2
সি ++ 11 আপনাকে এখন স্ট্রাক্ট বা শ্রেণীর সংজ্ঞায় এগুলি আরম্ভ করার অনুমতি দেয়: স্ট্র্যাপ স্ন্যাপশট {ডাবল এক্স {0}; // সহ ধনুর্বন্ধনী int y = 0; // অথবা কেবলমাত্র পুরানো স্কুল শৈলী 'অ্যাসাইনাইমেন্ট দ্বারা' যা সত্যিকার অর্থেই আরম্ভও};
ikku100

1
"স্ন্যাপশট s = {};" মান অংশ?
স্টিফান

40

না, তারা ডিফল্টরূপে 0 নয়। সমস্ত মান বা 0 এ ডিফল্ট হওয়া নিশ্চিত করার সহজ উপায়টি হল একজন কনস্ট্রাক্টরকে সংজ্ঞায়িত করা

Snapshot() : x(0), y(0) {
}

এটি নিশ্চিত করে যে স্ন্যাপশটের সমস্ত ব্যবহারের প্রাথমিক মানের মান থাকবে।


24
ক্ষতিটি হ'ল স্ট্রাকটি আর কোনও পিওডি টাইপ নয়, কারণ এতে কনস্ট্রাক্টর রয়েছে। এটি অস্থায়ী ফাইলে এটি লেখার মতো কিছু ক্রিয়াকলাপ ভাঙবে।
ফাইনাল

16
@ ফিনওয়ান: সি ++ 11 এটিকে ঠিক করে, যদিও স্ট্রাকটি পড নয়, এটি "স্ট্যান্ডার্ড লেআউট"।
বেন ভয়েগট

19

সাধারণভাবে, না। তবে কোনও ফাংশনে ফাইল-স্কোপ বা স্থিতিশীল হিসাবে ঘোষিত একটি স্ট্রাক্ট / উইল / এ 0 টি শুরু হবে (ঠিক সেই সমস্ত স্কোপের অন্যান্য ভেরিয়েবলের মতো):

int x; // 0
int y = 42; // 42
struct { int a, b; } foo; // 0, 0

void foo() {
  struct { int a, b; } bar; // undefined
  static struct { int c, d; } quux; // 0, 0
}

1
এটি আসলেই নিরাপদ অনুমান নয়। আপনি আরম্ভ করেননি এমন কোনও কিছুর মূল্যের উপর নির্ভর করা উচিত নয়
হস্তুরকুন

24
স্ট্যাটিক স্টোরেজ সময়কাল অবজেক্টগুলি সর্বদা শূন্য থেকে শুরু করা হয় - স্ট্যান্ডার্ড থেকে উদ্ধৃতি দেওয়ার জন্য স্ট্যাকওভারফ্লো.com/ প্রশ্নগুলি / 60653 /… দেখুন । এটি ভাল স্টাইল কিনা তা অন্য বিষয়।
বিডনলান

12

পিওডের সাহায্যে আপনিও লিখতে পারেন

Snapshot s = {};

আপনার সি ++ তে মেমসেট ব্যবহার করা উচিত নয়, মেমসেটের একটি অপূর্ণতা রয়েছে যে স্ট্রাক্টে যদি কোনও নন-পড থাকে তবে এটি এটি নষ্ট করে দেবে।

বা এই মত:

struct init
{
  template <typename T>
  operator T * ()
  {
    return new T();
  }
};

Snapshot* s = init();

নিবন্ধন করুন
বেন সিনক্লেয়ার

@ অ্যান্ডি মোস্ট ভেক্সিং পার্স এমন জিনিসগুলিকে পরিণত হয় যা সাধারণ কর্টোর মতো লাগে - SomeType foo();এটি সাধারণত একটি, যদিও এটি অন্যদের সাথে ঘটতে পারে - ফাংশন সংজ্ঞাতে (সেই ক্ষেত্রে, একটি ফাংশন fooযা ফিরে আসে SomeType)। নেক্রোর জন্য দুঃখিত, তবে অন্য কেউ যদি এইজন্য হোঁচট খায় তবে আমি উত্তর দেব।
তহবিল মনিকার লসুইট

7

সি ++ এ নো-আর্গুমেন্ট কনস্ট্রাক্টর ব্যবহার করুন। সি তে আপনার কাছে কনস্ট্রাক্টর থাকতে পারে না, তাই হয় memsetবা - আকর্ষণীয় সমাধান - মনোনীত প্রারম্ভিক ব্যবহার করুন:

struct Snapshot s = { .x = 0.0, .y = 0.0 };

আমি বিশ্বাস করি এটি সি ,++ নয়। এটি কিছু সি ++ কম্পাইলারের অধীনে সংকলন করতে ব্যর্থ হবে। আমি সাইগউইন বা মিনজিডব্লিউয়ের অধীনে সংকলন ব্যর্থতা অনুভব করেছি।
jww

3

আমি বিশ্বাস করি সঠিক উত্তরটি হ'ল তাদের মানগুলি সংজ্ঞায়িত। কোডের ডিবাগ সংস্করণগুলি চালানোর সময় প্রায়শই এগুলিতে 0 থেকে শুরু হয়। রিলিজ সংস্করণগুলি চালানোর সময় এটি সাধারণত হয় না।


2
প্রকৃতপক্ষে ডিবাগ সংস্করণগুলি 0স্মৃতিতে সেই জায়গাগুলিতে ইতিমধ্যে ঘটবে । এটি আরম্ভের মতো নয়!
অরবিটে

3

যেহেতু এটি একটি পিওডি (মূলত একটি সি স্ট্রাক্ট) তাই এটি সি পদ্ধতিতে আরম্ভ করার ক্ষেত্রে খুব কম ক্ষতি হয়:

Snapshot s;
memset(&s, 0, sizeof (s));

বা একইভাবে

Snapshot *sp = new Snapshot;
memset(sp, 0, sizeof (*sp));

যদিও আমি এখনও calloc()সি ++ প্রোগ্রামে ব্যবহার করতে পারি না।


3
একই ডাবল জন্য হোল্ড; অল-বিট-শূন্য অগত্যা 0.0 নয়। যাইহোক, আপনি যদি আইইইই 75 double৫ ডাবলস পরীক্ষা করে দেখতে পারেন তবে এটি অবশ্যই কার্যকর হবে।
MSalters

1

পড সদস্যদের আপনার প্রাথমিকের তালিকাটি সংক্ষিপ্ত করতে বেস শ্রেণিতে স্থানান্তর করুন:

struct foo_pod
{
    int x;
    int y;
    int z;
};

struct foo : foo_pod
{
    std::string name;
    foo(std::string name)
        : foo_pod()
        , name(name)
    {
    }
};

int main()
{
    foo f("bar");
    printf("%d %d %d %s\n", f.x, f.y, f.z, f.name.c_str());
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.