ইন সি ++ , সেখানে মধ্যে কোনো পার্থক্য নেই:
struct Foo { ... };
এবং:
typedef struct { ... } Foo;
ইন সি ++ , সেখানে মধ্যে কোনো পার্থক্য নেই:
struct Foo { ... };
এবং:
typedef struct { ... } Foo;
উত্তর:
সি ++ এ কেবল একটি সূক্ষ্ম পার্থক্য রয়েছে। এটি সি থেকে একটি হোল্ডওভার, এতে এটি একটি পার্থক্য করে।
সি ভাষার মান ( C89 893.1.2.3 , C99 §6.2.3 , এবং C11 .26.2.3 ) ট্যাগ শনাক্তকারীদের ( struct
/ union
/ enum
) এবং সাধারণ সনাক্তকারীদের ( typedef
এবং অন্যান্য শনাক্তকারীদের জন্য ) সহ বিভিন্ন বিভাগের শনাক্তকারীদের জন্য পৃথক নেমস্পেসগুলি নির্দেশ করে ates ।
আপনি যদি কেবল বলেছেন:
struct Foo { ... };
Foo x;
আপনি একটি সংকলক ত্রুটি পাবেন, কারণ Foo
শুধুমাত্র ট্যাগ নেমস্পেসে সংজ্ঞায়িত।
আপনি এটি হিসাবে ঘোষণা করতে চাই:
struct Foo x;
আপনি যে কোনও সময় রেফারেন্স করতে চান Foo
, আপনাকে সর্বদা এটিকে ডাকতে হবে struct Foo
। এটি বিরক্তিকর দ্রুত হয়, যাতে আপনি একটি যুক্ত করতে পারেন typedef
:
struct Foo { ... };
typedef struct Foo Foo;
এখন struct Foo
(ট্যাগ নেমস্পেসে) এবং কেবল প্লেইন Foo
(সাধারণ শনাক্তকারী নেমস্পেসে) উভয়ই একই জিনিসটিকে বোঝায় এবং আপনি কীওয়ার্ড Foo
ছাড়াই নির্বিঘ্নে টাইপের অবজেক্টগুলি ঘোষণা করতে পারেন struct
।
নির্মাণ:
typedef struct Foo { ... } Foo;
ঘোষণার জন্য কেবল একটি সংক্ষেপণ এবং typedef
।
অবশেষে,
typedef struct { ... } Foo;
একটি বেনামি কাঠামো ঘোষণা করে এবং এর typedef
জন্য একটি তৈরি করে। সুতরাং, এই নির্মাণের সাথে, ট্যাগ নেমস্পেসে এটির একটি নাম নেই, কেবল টাইপডেফ নেমস্পেসের একটি নাম। এর অর্থ এটিও এগিয়ে ঘোষণা করা যায় না। আপনি যদি কোনও ফরওয়ার্ড ঘোষণা করতে চান তবে আপনাকে ট্যাগ নেমস্পেসে একটি নাম দিতে হবে ।
সি ++ এ, সমস্ত struct
/ union
/ enum
/ class
ঘোষণাগুলি এগুলি স্পষ্টতই typedef
'এড' এর মতো কাজ করে , যতক্ষণ না একই নামের সাথে অন্য কোনও ঘোষণার মাধ্যমে নামটি গোপন করা হয় না। দেখুন মাইকেল চোরকাঁটা এর উত্তর সম্পূর্ণ বিবরণের জন্য।
ইন এই DDJ নিবন্ধ , ড্যান Saks এক ছোটো এলাকার যেখানে বাগ মাধ্যমে হামাগুড়ি পারেন যদি আপনি আপনার structs মধ্যে হয় typedef না ব্যাখ্যা (এবং ক্লাস!):
আপনি যদি চান তবে আপনি কল্পনা করতে পারেন যে সি ++ প্রতিটি ট্যাগ নামের জন্য টাইপডেফ তৈরি করে
typedef class string string;
দুর্ভাগ্যক্রমে, এটি সম্পূর্ণ সঠিক নয়। আমি আশা করি এটি সহজ ছিল, কিন্তু এটি না। সি ++ সি এর সাথে অসঙ্গতিগুলি প্রবর্তন না করে স্ট্রাক্ট, ইউনিয়ন বা এনামগুলির জন্য এ জাতীয় টাইপডেফ তৈরি করতে পারে না
উদাহরণস্বরূপ, ধরুন একটি সি প্রোগ্রাম কোনও ফাংশন এবং স্ট্রাক্ট নামের স্থিতি উভয়ই ঘোষণা করেছে:
int status(); struct status;
আবার এটি খারাপ অভ্যাস হতে পারে তবে এটি সি। এই প্রোগ্রামে স্ট্যাটাস (নিজে থেকেই) ফাংশনকে বোঝায়; কাঠামোর অবস্থা প্রকারকে বোঝায়।
যদি সি ++ ট্যাগগুলির জন্য স্বয়ংক্রিয়ভাবে টাইপডেফ তৈরি করে, তবে আপনি যখন এই প্রোগ্রামটি সি ++ হিসাবে সংকলন করবেন তখন সংকলকটি উত্পন্ন করবে:
typedef struct status status;
দুর্ভাগ্যক্রমে, এই ধরণের নামটি ফাংশন নামের সাথে বিরোধ করবে এবং প্রোগ্রামটি সংকলন করবে না। এজন্য সি ++ প্রতিটি ট্যাগের জন্য কেবল টাইপডেফ তৈরি করতে পারে না।
সি ++ এ, ট্যাগগুলি টাইপিডেফ নামের মতোই কাজ করে, ব্যতিরেকে যে কোনও প্রোগ্রাম কোনও নাম, ট্যাগ এবং একই স্কোপ সহ একটি অবজেক্ট, ফাংশন, বা গণক ঘোষণা করতে পারে। সেক্ষেত্রে, অবজেক্ট, ফাংশন, বা গণকের নাম ট্যাগের নামটি গোপন করে। প্রোগ্রামটি কেবল ট্যাগ নামের সামনে কীওয়ার্ড শ্রেণি, কাঠামো, ইউনিয়ন বা এনাম (যথাযথ) ব্যবহার করে ট্যাগের নামটি উল্লেখ করতে পারে। ট্যাগগুলির পরে এই কীওয়ার্ডগুলির মধ্যে একটির সমন্বিত একটি প্রকারের নাম একটি বিস্তৃত-টাইপ-স্পেসিফায়ার। উদাহরণস্বরূপ, কাঠামোর স্থিতি এবং এনাম মাস সবিস্তারে টাইপ-স্পেসিফায়ার।
সুতরাং, একটি সি প্রোগ্রাম যাতে উভয় থাকে:
int status(); struct status;
সি ++ হিসাবে সংকলিত হওয়ার সময় একই আচরণ করে। নাম স্থিতি একা ফাংশন বোঝায়। প্রোগ্রামটি কেবল বর্ণিত-টাইপ-স্পেসিফায়ার স্ট্রাক স্থিতি ব্যবহার করে প্রকারটি উল্লেখ করতে পারে।
তাহলে কীভাবে এটি বাগগুলিকে প্রোগ্রামগুলিতে ডুবে যেতে দেয়? তালিকা 1 এ প্রোগ্রামটি বিবেচনা করুন । এই প্রোগ্রামটি একটি ডিফল্ট কন্সট্রাক্টর এবং একটি রূপান্তরকারী অপারেটর সহ একটি ক্লাস ফু সংজ্ঞায়িত করে যা কোনও foo অবজেক্টটিকে চর কনস্ট * রূপান্তর করে। এখনও বিক্রয়ের জন্য
p = foo();
মূলত একটি foo অবজেক্ট তৈরি করা উচিত এবং রূপান্তর অপারেটর প্রয়োগ করা উচিত। পরবর্তী আউটপুট বিবৃতি
cout << p << '\n';
ক্লাস foo প্রদর্শন করা উচিত, কিন্তু এটি না। এটি ফাংশন ফু প্রদর্শন করে।
এই আশ্চর্যজনক ফলাফলটি ঘটে কারণ প্রোগ্রামটি 2 টি তালিকায় প্রদর্শিত শিরোনাম lib.h অন্তর্ভুক্ত করে । এই শিরোনাম foo নামে একটি ফাংশন সংজ্ঞায়িত করে। ফাংশন নেম foo ক্লাসের নাম foo গোপন করে, সুতরাং foo- র মূল উল্লেখটি ফাংশনকে বোঝায়, শ্রেণি নয়। মেইন কেবলমাত্র একটি বিস্তৃত-টাইপ-স্পেসিফায়ার ব্যবহার করে ক্লাসটি উল্লেখ করতে পারে
p = class foo();
পুরো প্রোগ্রাম জুড়ে এই জাতীয় বিভ্রান্তি এড়ানোর উপায়টি ক্লাস নাম foo এর জন্য নিম্নলিখিত টাইপডেফ যুক্ত করা:
typedef class foo foo;
ক্লাস সংজ্ঞা আগে বা পরে অবিলম্বে। এই টাইপডিফ প্রকারের নাম foo এবং ফাংশন নাম foo (লাইব্রেরি থেকে) এর মধ্যে দ্বন্দ্ব সৃষ্টি করে যা একটি সংকলন-সময় ত্রুটি ট্রিগার করবে।
আমি অবশ্যই জানি না যে যিনি এই টাইপডেফগুলি অবশ্যই লেখেন writes এটির জন্য প্রচুর শৃঙ্খলা দরকার। যেহেতু তালিকার 1 এর মতো ত্রুটির ঘটনাগুলি সম্ভবত খুব ছোট, তাই আপনারা অনেকেই কখনও এই সমস্যাটি থেকে দূরে থাকেন না। তবে যদি আপনার সফ্টওয়্যারটিতে কোনও ত্রুটি শারীরিকভাবে আঘাতের কারণ হতে পারে তবে ত্রুটি যতই কমই হোক না কেন আপনার টাইপএফগুলি লিখতে হবে।
আমি কখনই ক্লাসের মতো একই স্কোপে কোনও ফাংশন বা অবজেক্টের নাম সহ কোনও শ্রেণীর নাম কেন গোপন করতে চাইবে তা আমি ভাবতে পারি না। সি-তে লুকানোর নিয়মগুলি একটি ভুল ছিল এবং সেগুলি সি ++ এর ক্লাসে প্রসারিত করা উচিত হয়নি। প্রকৃতপক্ষে, আপনি ভুলটি সংশোধন করতে পারেন, তবে এটির জন্য অতিরিক্ত প্রোগ্রামিং শৃঙ্খলা এবং প্রচেষ্টা প্রয়োজন যা প্রয়োজন হবে না।
Listing 1
এবং Listing 2
লিঙ্কগুলি নষ্ট হয়ে গেছে। একবার দেখুন।
আরও একটি গুরুত্বপূর্ণ পার্থক্য: typedef
গুলি এগিয়ে ঘোষণা করা যায় না। তাই জন্য typedef
বিকল্পটি আবশ্যক #include
ফাইল ধারণকারী typedef
, সবকিছু অর্থ #include
করা আপনার .h
কাছে যে ফাইল তা সরাসরি দরকার বা না, ইত্যাদি অন্তর্ভুক্ত করা হয়েছে। এটি অবশ্যই বড় প্রকল্পগুলিতে আপনার বিল্ড বারকে প্রভাবিত করতে পারে।
ছাড়া typedef
, কিছু কিছু ক্ষেত্রে আপনি শুধু একটা ফরওয়ার্ড ঘোষণা যোগ করতে পারেন struct Foo;
আপনার উপরের .h
ফাইল, এবং শুধুমাত্র #include
আপনার struct সংজ্ঞা .cpp
ফাইল।
সেখানে হয় একটি পার্থক্য, কিন্তু সূক্ষ্ম। এটি এইভাবে দেখুন: struct Foo
একটি নতুন টাইপ প্রবর্তন। দ্বিতীয়টি একটি নামবিহীন struct
প্রকারের জন্য ফু (এবং কোনও নতুন ধরণের নয়) নামে একটি উপনাম তৈরি করে ।
7.1.3 টাইপডেফ নির্দিষ্টকরণকারী specif
1 [...]
টাইপডেফ স্পেসিফায়ারের সাথে ঘোষিত একটি নাম টাইপএফ-নাম হয়ে যায়। এর ঘোষণার ক্ষেত্রের মধ্যে, একটি টাইপিডেফ-নামটি মূলত একটি কীওয়ার্ডের সমতুল্য এবং ক্লোজ ৮-এ বর্ণিত পদ্ধতিতে সনাক্তকারীর সাথে সম্পর্কিত ধরণের নামকরণ করে A টাইপডেফ-নামটি অন্যভাবে একটি প্রতিশব্দ। ক্লাস ঘোষণাপত্র (9.1) বা এনাম ডিকোলেমেশন যেভাবে টাইপইফ -নাম একটি নতুন ধরণের প্রবর্তন করে না ।
8 যদি টাইপডেফ ঘোষণাপত্র একটি নামবিহীন শ্রেণি (বা এনাম) সংজ্ঞায়িত করে তবে ঘোষণাপত্রের দ্বারা ঘোষিত প্রথম টাইপডিফ-নামটি শ্রেণীর প্রকার (বা এনাম টাইপ) হিসাবে সংযোগের উদ্দেশ্যে কেবল শ্রেণিবদ্ধ (বা এনাম টাইপ) বোঝাতে ব্যবহৃত হয় ( 3.5)। [উদাহরণ:
typedef struct { } *ps, S; // S is the class name for linkage purposes
সুতরাং, একটি টাইপিডেফ সর্বদা অন্য ধরণের স্থানধারক / প্রতিশব্দ হিসাবে ব্যবহৃত হয়।
আপনি টাইপডেফ স্ট্রাক্টের সাথে ফরোয়ার্ড ঘোষণাটি ব্যবহার করতে পারবেন না।
কাঠামো নিজেই একটি বেনামি ধরণের, সুতরাং আপনার কাছে ফরওয়ার্ড দেওয়ার জন্য প্রকৃত নাম নেই।
typedef struct{
int one;
int two;
}myStruct;
এই অদম্য কাজের মতো একটি অগ্রণী ঘোষণা:
struct myStruct; //forward declaration fails
void blah(myStruct* pStruct);
//error C2371: 'myStruct' : redefinition; different basic types
myStruct
নেমস্পেসে টাইপ লাইফ এবং টাইপডেফ_ড myStruct
জীবন স্বাভাবিক নামস্থানে থাকে যেখানে অন্যান্য শনাক্তকারী যেমন ফাংশন নাম, স্থানীয় পরিবর্তনশীল নামগুলি বাস করে So
typedef
সাথে একটি , এগিয়ে ঘোষণা typedef
, নামবিহীন কাঠামোটি উল্লেখ করে না। পরিবর্তে ফরোয়ার্ড ঘোষণাটি ট্যাগ সহ একটি অসম্পূর্ণ কাঠামো ঘোষণা করে myStruct
। এছাড়াও, সংজ্ঞাটি না দেখে typedef
, typedef
এড নাম ব্যবহার করে ফাংশন প্রোটোটাইপ আইনী নয়। সুতরাং যখনই আমাদের myStruct
কোনও প্রকার বোঝাতে প্রয়োজন তখন আমাদের পুরো টাইপডেফটি অন্তর্ভুক্ত করতে হবে । আমি আপনাকে ভুল বুঝে থাকলে আমাকে সংশোধন করুন। ধন্যবাদ।
সি ++ তে একটি 'টাইপডিফ স্ট্রাক্ট' এবং 'স্ট্রাক্ট' এর মধ্যে একটি গুরুত্বপূর্ণ পার্থক্য হ'ল টাইপডেফ স্ট্রাইকগুলিতে ইনলাইন সদস্য সূচনাটি কাজ করবে না।
// the 'x' in this struct will NOT be initialised to zero
typedef struct { int x = 0; } Foo;
// the 'x' in this struct WILL be initialised to zero
struct Foo { int x = 0; };
x
সূচনা করা হয়। কলিরু অনলাইন আইডিইতে পরীক্ষা দেখুন (আমি এটিকে 42 দিয়ে শুরু করেছিলাম তাই কাজটি শূন্যের চেয়ে আরও বেশি স্পষ্ট যে অ্যাসাইনমেন্টটি সত্যই ঘটেছে)।