সি ++ এ বাহ্যিকটি কখন ব্যবহার করবেন


398

আমি "থিঙ্ক ইন সি ++" পড়ছি এবং এটি সবেমাত্র externঘোষণাটি প্রবর্তন করেছে । উদাহরণ স্বরূপ:

extern int x;
extern float y;

আমি মনে করি আমি এর অর্থটি (সংজ্ঞা ছাড়াই ঘোষণা) বুঝতে পেরেছি, তবে কখন তা কার্যকর প্রমাণিত হয় তা অবাক করি।

কেউ উদাহরণ দিতে পারে?


1
আমাকে externবেশ কয়েকটি অনুষ্ঠানে একটি সংজ্ঞা দিতে হয়েছিল। মাইক্রোসফ্ট সরঞ্জামগুলি প্রতীক হারিয়ে যাওয়ার জন্য একটি লিঙ্ক ত্রুটি তৈরি করেছিল যখন অন্য উত্স ফাইলের টেবিলগুলি কেবলমাত্র সংজ্ঞায়িত করা হত। সমস্যাটি ছিল, সারণীটি ছিল constএবং সি ++ সংকলকটি staticঅনুবাদ ইউনিটে উন্নীত করে । উদাহরণস্বরূপ দেখুন, ariatab.cppএবং kalynatab.cpp
jww

2
এবং আমার কাছে নিকের উত্তরটি সঠিক বলে মনে হচ্ছে কারণ তিনিই একমাত্র সি ++ প্রশ্নের উত্তর দিয়েছেন বলে মনে হয়। অন্য প্রত্যেকে সি সি প্রশ্নে আকৃষ্ট হয়েছে বলে মনে হয়।
jww

উত্তর:


519

আপনার যখন বৈশ্বিক ভেরিয়েবল থাকে এটি কার্যকর হয়। আপনি একটি শিরোনামে গ্লোবাল ভেরিয়েবলের অস্তিত্ব ঘোষণা করেন , যাতে প্রতিটি সূত্রের ফাইল যা শিরোনামটি অন্তর্ভুক্ত করে এটি সম্পর্কে জানতে পারে তবে আপনার উত্স ফাইলগুলির মধ্যে একবারে এটি কেবল "সংজ্ঞায়িত" করতে হবে।

স্পষ্ট করতে, সংকলককে extern int x;বলে যে intনামক একটি বস্তু কোথাওx উপস্থিত রয়েছে । এটি কোথায় রয়েছে তা জানা সংকলকগুলির কাজ নয়, এটির প্রকার এবং নাম জানা দরকার তাই এটি কীভাবে এটি ব্যবহার করতে হয় তা জানে। একবার উত্স ফাইলগুলির সমস্ত সংকলিত হয়ে গেলে, লিঙ্কার সংকলিত উত্স ফাইলগুলির মধ্যে একটিতে এটি খুঁজে পাওয়া একটি সংজ্ঞাটির সমস্ত উল্লেখগুলি সমাধান করবে । এটির কাজ করার জন্য, ভেরিয়েবলের সংজ্ঞাটিকে "বাহ্যিক সংযোগ" বলা দরকার যা মূলত এর অর্থ এটি কোনও ফাংশনের বাইরে (সাধারণত "ফাইল স্কোপ" বলা হয়) এবং কীওয়ার্ড ছাড়াই ঘোষণা করা দরকার ।xxstatic

শিরোলেখ:

#ifndef HEADER_H
#define HEADER_H

// any source file that includes this will be able to use "global_x"
extern int global_x;

void print_global_x();

#endif

উত্স 1:

#include "header.h"

// since global_x still needs to be defined somewhere,
// we define it (for example) in this source file
int global_x;

int main()
{
    //set global_x here:
    global_x = 5;

    print_global_x();
}

উত্স 2:

#include <iostream>
#include "header.h"

void print_global_x()
{
    //print global_x here:
    std::cout << global_x << std::endl;
}

15
ধন্যবাদ. সুতরাং, যদি আমি বাহ্যিক কীওয়ার্ড ব্যতীত একটি শিরোনামের ফাইলে একটি বৈশ্বিক পরিবর্তনশীল ঘোষণা করি, তবে শিরোনামযুক্ত ফাইলগুলি যা শিরোনামটি অন্তর্ভুক্ত করে তা এটি দেখতে পাবে না?
Aslan986

23
আপনি একটি শিরোনামে গ্লোবাল ভারগুলি ঘোষণা করবেন না, কারণ এরপরে যখন 2 টি ফাইল একই শিরোলেখ ফাইলটি অন্তর্ভুক্ত করে তখন এটি লিঙ্ক করবে না (লিঙ্কারটি "সদৃশ প্রতীক" সম্পর্কে একটি ত্রুটি নির্গত করবে)
কুবা

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

7
আপনি যখন "বাহ্য" শব্দটি ব্যবহার করবেন না, তখন এখন ভেরিয়েবলটি বিদ্যমান। আপনি যখন "বাহ্যিক" ব্যবহার করেন, এটি "আরে অন্য কোথাও এই রকম আছে"। এটি কোনও সংজ্ঞা বা ঘোষণার জবাব না দেওয়ার জন্য দুঃখিত, যেহেতু আমি এই দুটি সম্পর্কে সর্বদা বিভ্রান্ত হয়ে পড়েছি।
কুবা

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

172

যখন আপনি কয়েকটি মডিউলগুলির মধ্যে কোনও ভেরিয়েবল ভাগ করেন এটি কার্যকর। আপনি এটি একটি মডিউলে সংজ্ঞায়িত করুন এবং অন্যগুলিতে এক্সটারন ব্যবহার করুন।

উদাহরণ স্বরূপ:

file1.cpp এ:

int global_int = 1;

file2.cpp এ:

extern int global_int;
//in some function
cout << "global_int = " << global_int;

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

1
নেমস্পেসগুলি জড়িত থাকাকালীন, global_intগ্লোবাল নেমস্পেসের সাথে জড়িত থাকার পরেও কি কোনও গ্যাটাচস রয়েছে, যদি আমি ফাইল -২০ পিপি-তে এটি কোনও নাম-স্থান বিভাগে ব্যবহার করি তবে আমাকে এটিকে সঠিক করতে হবে? অর্থাত্namespace XYZ{ void foo(){ ::global_int++ } };
jxramos

8
@ জ্যাক: অন্যদিকে, শিরোনামে গ্লোবাল ভেরিয়েবল ঘোষণা না করে আপনি অজান্তে এটি কোথায় সংজ্ঞায়িত হয়েছে তা নির্ধারণ করা আরও বেশি কঠিন করে তুলেছেন। সাধারণত আপনি যদি বিশ্বব্যাপী ঘোষিত ঘোষিত ঘোষিত দেখতে পান তবে abc.hএটির সংজ্ঞা দেওয়ার একটা ভাল সুযোগ রয়েছে abc.cpp। একটি ভাল আইডিই সর্বদা সহায়তা করবে তবে সুসংহত কোড সর্বদা একটি ভাল সমাধান solution
ড্রিমলাক্স

externfile2.cpp ছাড়া , এখনও global_intঅন্তর্ভুক্ত অ্যাক্সেস করতে পারেন । আমার এটা কেন দরকার?
টমসওয়ায়ার

62

এটা সব লিঙ্কেজ সম্পর্কে ।

পূর্ববর্তী উত্তর সম্পর্কে ভাল ব্যাখ্যা প্রদান extern

তবে আমি একটি গুরুত্বপূর্ণ বিষয় যুক্ত করতে চাই।

আপনি সম্পর্কে জিজ্ঞাসা externমধ্যে সি ++ নেই সেঃ এবং আমি জানি না কেন মামলা উল্লেখ উত্তর নেই যখন externদিয়ে আসে constC ++।

সি ++ এ, কোনও constভেরিয়েবলের ডিফল্টরূপে অভ্যন্তরীণ সংযোগ থাকে (সিটির মতো নয়)।

সুতরাং এই পরিস্থিতিতে লিঙ্কিং ত্রুটির দিকে পরিচালিত করবে :

উত্স 1:

const int global = 255; //wrong way to make a definition of global const variable in C++

উত্স 2:

extern const int global; //declaration

এটি এর মতো হওয়া দরকার:

উত্স 1:

extern const int global = 255; //a definition of global const variable in C++

উত্স 2:

extern const int global; //declaration

2
সংজ্ঞা অংশে 'এক্সটার্নাল' অন্তর্ভুক্ত না করে সি ++ এ কাজ করার সময় কেন এটি ভুল?
চিফ শিফটার

1
ভিসুয়াল স্টুডিওতে ভিজ্যুয়াল মাইক্রো দিয়ে এই লিঙ্কিংয়ের ত্রুটির মুখোমুখি হতে দেখছি না। আমি কী মিস করছি?
ক্রেগ.ফিড

1
@ লরিস্টিস্ট ৯৩ @ ক্রেগ.ফিডে আমি বিশ্বাস করি আপনার আবার সাবধানতার সাথে পরীক্ষা করার প্রয়োজন হতে পারে। সংযোগকারী যদি লিঙ্কিংয়ের ত্রুটিটি অবহিত করে না, আপনি কি উভয় উত্সের উভয় বস্তু externসংজ্ঞা ছাড়াই একই পরীক্ষা করতে পারবেন ? globalউত্স 2 এর মান মুদ্রণ করে আপনি এটি করতে পারেন
ট্রেভর

3
নিশ্চিত করেন, MSVS 2018 সালে সেখানে হয় একটি লিঙ্ক ত্রুটি যদি externবাদ দেওয়া হয় const int global = 255;
এভগ

13

আপনি যখন বৈশ্বিক চলক রাখতে চান এটি এটি কার্যকর is আপনি কিছু সোর্স ফাইলে গ্লোবাল ভেরিয়েবলগুলি সংজ্ঞায়িত করেছেন এবং এগুলি একটি শিরোনাম ফাইলে বহিরাগত হিসাবে ঘোষণা করেছেন যাতে যে কোনও ফাইলের মধ্যে যা শিরোনাম ফাইলটি অন্তর্ভুক্ত করে তারপরে একই বৈশ্বিক চলক দেখতে পাবে।


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