ক্লাসের ভিতরে বা বাইরে ফাংশন ডিক্লারেশন


91

আমি একটি জাভা বিকাশকারী, যিনি সি ++ শিখার চেষ্টা করছেন, তবে মানক ফাংশন ঘোষণার জন্য সেরা অনুশীলন কী তা আমি সত্যিই জানি না।

ক্লাসে:

class Clazz
{
 public:
    void Fun1()
    {
        //do something
    }
}

বা বাইরে:

class Clazz
{
public:
    void Fun1();
}

Clazz::Fun1(){
    // Do something
}

আমার একটা অনুভূতি আছে যে দ্বিতীয়টি কম পাঠযোগ্য হতে পারে ...


4
এখানে আসলে 3 টি বিকল্প রয়েছে। আপনার দ্বিতীয় উদাহরণটির শিরোনাম ফাইলটিতে ফাংশন সংজ্ঞা থাকতে পারে (তবে এখনও ইনলাইন করা হয়নি), বা একটি পৃথক .cppফাইলে।
কোডি গ্রে

এই প্রশ্নটি আপনাকে বুঝতে সাহায্য করবে।
বিজির্ন পোলেক্স

4
কেবল একটি নোট: ঘোষণাটি সর্বদা শ্রেণীর ভিতরে থাকে তবে সংজ্ঞাটি হয় ভিতরে বা বাইরে। প্রশ্ন শিরোনাম এবং বডি s / ঘোষণা / সংজ্ঞা সাপেক্ষে করা উচিত / আমাকে বিশ্বাস করবেন না? stackoverflow.com/q/1410563/1143274
এভেজেনি সার্জিভ

4
শ্রেণীর অভ্যন্তরে ফাংশন সংজ্ঞাগুলি এড়ানো উচিত। তারা নিখুঁতভাবে গণ্য করা হয় inline
জন স্ট্রুড

@ জনস্ট্র্রুড তাই? inlineকেবলমাত্র একটি সংজ্ঞা নিয়ম শিথিল করে, যা অন্য অনুবাদ ইউনিট ব্যবহার করলে প্রয়োজনীয়Clazz
কালেথ

উত্তর:


57

সি ++ হ'ল অবজেক্ট অরিয়েন্টেড, এই অর্থে যে এটি সফ্টওয়্যার বিকাশের জন্য অবজেক্ট ওরিয়েন্টড দৃষ্টান্তকে সমর্থন করে।

তবে জাভা থেকে আলাদাভাবে, সি ++ আপনাকে ক্লাসে ফাংশন সংজ্ঞা গোষ্ঠী করতে বাধ্য করে না: একটি ক্রিয়াকলাপ ঘোষণার জন্য স্ট্যান্ডার্ড সি ++ উপায়টি কোনও শ্রেণি ছাড়াই কেবল একটি ফাংশন ঘোষণা করা।

পরিবর্তে আপনি যদি পদ্ধতি ঘোষণার / সংজ্ঞা সম্পর্কে কথা বলছেন তবে মানক উপায়টি হ'ল ঘোষণাকে একটি অন্তর্ভুক্ত ফাইল (সাধারণত নামযুক্ত .hবা .hpp) এবং সংজ্ঞাটি একটি পৃথক বাস্তবায়ন ফাইলে (সাধারণত নামকরণ করা হয় .cppবা .cxx) রাখা উচিত। আমি সম্মতি জানাই এটি সত্যই কিছুটা বিরক্তিকর এবং এর জন্য কিছু নকলের প্রয়োজন তবে ভাষাটি কীভাবে ডিজাইন করা হয়েছিল।

দ্রুত পরীক্ষা-নিরীক্ষা এবং একক ফাইল প্রকল্পের জন্য যে কোনও কিছু কাজ করবে ... তবে বড় প্রকল্পগুলির জন্য এই বিচ্ছেদটি এমন কিছু যা ব্যবহারিকভাবে প্রয়োজনীয়।

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

সি ++ শেখার একমাত্র যুক্তিযুক্ত উপায় হ'ল পাঠ করা ... আপনি যতই স্মার্ট হোন না কেন কমিটি কী সিদ্ধান্ত নিয়েছে তা অনুমান করার কোনও উপায় নেই (আসলে স্মার্ট হওয়া অনেক সময় এমনকি সমস্যা এমনকি কারণ সঠিক উত্তরটি অযৌক্তিক এবং historicalতিহাসিক ফলাফল) heritageতিহ্য।)

কেবল একটি ভাল দুটি বাছাই করুন এবং তাদের কভারটি কভার পড়ুন।


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

4
@ ড্যানিয়েলস: স্পষ্টতই আপনাকে ক্ষতিগ্রস্থ করেছে (কেন জানি না) এই অংশটি সরানো হয়েছে। নিশ্চিতভাবেই আমি জাভা সম্পর্কে রেটিং করছি না কারণ আমি আসলে জাভা ব্যবহার করি না, আমি কেবল তখন ভেবেছিলাম যে অবজেক্ট অবসেসড প্রোগ্রামিং হিসাবে ওওপি একটি মজার রসিকতা ছিল, যদিও দৃশ্যত এটি তা নয়। আমি জাভা ১.১ সার্টিফাইড প্রোগ্রামার হয়েছি কিন্তু তখনই সিদ্ধান্ত নিয়েছি, যদি কোনও কারণে বাধ্য না করা হয় তবে আমি সেই "প্রোগ্রামিং ল্যাঙ্গুয়েজ" ব্যবহার করব না এবং এ পর্যন্ত আমি এড়াতে সফল হয়েছি।
6502

ধন্যবাদ, আমি মনে করি এটি এখন আরও ভাল পড়ছে। আমি খারাপ মনে হলে দুঃখিত। আমি পরের বার আরও ইতিবাচক হওয়ার চেষ্টা করব।
ড্যানিয়েল এস

15
প্রশ্নের উত্তর দেয় না
পেটর পেলার

4
@ পেটারপেলার: তৃতীয় অনুচ্ছেদের অংশটি কী আপনার কাছে পরিষ্কার নয়?
6502

27

প্রথমটি আপনার সদস্য ফাংশনটিকে একটি ইনলাইন ফাংশন হিসাবে সংজ্ঞায়িত করে , যখন দ্বিতীয়টি করে না। এই ক্ষেত্রে ফাংশনটির সংজ্ঞা শিরোনামের মধ্যেই থাকে।

দ্বিতীয় বাস্তবায়ন সিপিপি ফাইলে ফাংশনটির সংজ্ঞা রাখবে।

উভয় শব্দার্থগতভাবে পৃথক এবং এটি কেবল স্টাইলের বিষয় নয়।


4
cplusplus.com / ডক / টিউটোরিয়াল / স্লাসগুলি একই উত্তর দেয়: "শ্রেণীর সদস্য ফাংশনটিকে তার শ্রেণীর মধ্যে সম্পূর্ণরূপে সংজ্ঞায়িত করা বা কেবল প্রোটোটাইপ এবং পরে এর সংজ্ঞা অন্তর্ভুক্ত করার মধ্যে একমাত্র পার্থক্য, প্রথম ক্ষেত্রে ফাংশনটি স্বয়ংক্রিয়ভাবে হবে সংকলক দ্বারা একটি ইনলাইন সদস্য ফাংশন হিসাবে বিবেচিত হয়েছে, যখন দ্বিতীয়টিতে এটি একটি স্বাভাবিক (ইন-লাইন নয়) শ্রেণীর সদস্য ফাংশন হবে, যা বাস্তবে আচরণে কোনও পার্থক্য মনে করে না। "
বাটনস 840

18

ক্লাসের বাইরে ফাংশন সংজ্ঞা আরও ভাল। প্রয়োজনে আপনার কোডটি সুরক্ষিত থাকতে পারে। শিরোনাম ফাইলটি কেবল ঘোষণাপত্র দেওয়া উচিত।

মনে করুন যে কেউ আপনার কোড ব্যবহার করতে চায়, আপনি কেবল তাকে .h ফাইল এবং আপনার ক্লাসের .obj ফাইল (সংকলনের পরে প্রাপ্ত) দিতে পারেন। আপনার কোডটি ব্যবহার করার জন্য তার .cpp ফাইলের দরকার নেই।

আপনার বাস্তবায়ন অন্য কারও কাছে দৃশ্যমান নয়।


10

"ক্লাসের ভিতরে" (I) পদ্ধতিটি "শ্রেণীর বাইরে" (ও) পদ্ধতির মতোই হয়।

তবে, (আই) ব্যবহার করা যেতে পারে যখন একটি ক্লাস কেবল একটি ফাইলে ব্যবহৃত হয় (একটি .cpp ফাইলের অভ্যন্তরে)। (ও) ব্যবহৃত হয় যখন এটি একটি শিরোনাম ফাইলে থাকে। সিপিপি ফাইলগুলি সর্বদা সংকলিত হয়। যখন আপনি # শিরোনাম "অন্তর্ভুক্ত করেন তখন শিরোনামের ফাইলগুলি সংকলিত হয়।

আপনি যদি একটি শিরোনাম ফাইলে (I) ব্যবহার করেন তবে আপনি # শিরোনাম "অন্তর্ভুক্ত করুন প্রতিবার ফাংশন (ফান 1) ঘোষণা করা হবে। এটি একই ফাংশনটিকে একাধিকবার ঘোষণা করতে পারে। এটি সংকলন করা শক্ত এবং এমনকি ত্রুটি হতে পারে।

সঠিক ব্যবহারের জন্য উদাহরণ:

ফাইল 1: "ক্লজ হজ"

//This file sets up the class with a prototype body. 

class Clazz
{
public:
    void Fun1();//This is a Fun1 Prototype. 
};

ফাইল 2: "Clazz.cpp"

#include "Clazz.h" 
//this file gives Fun1() (prototyped in the header) a body once.

void Clazz::Fun1()
{
    //Do stuff...
}

ফাইল 3: "UseClazz.cpp"

#include "Clazz.h" 
//This file uses Fun1() but does not care where Fun1 was given a body. 

class MyClazz;
MyClazz.Fun1();//This does Fun1, as prototyped in the header.

ফাইল 4: "এছাড়াওউসক্লেজ.কম"

#include "Clazz.h" 
//This file uses Fun1() but does not care where Fun1 was given a body. 

class MyClazz2;
MyClazz2.Fun1();//This does Fun1, as prototyped in the header. 

ফাইল 5: "DoNotUseClazzHeader.cpp"

//here we do not include Clazz.h. So this is another scope. 
class Clazz
{
public:
    void Fun1()
    {
         //Do something else...
    }
};

class MyClazz; //this is a totally different thing. 
MyClazz.Fun1(); //this does something else. 

আপনার মানে Clazz MyClazzএবং Clazz MyClazz2?
চুপো_ক্রো

4

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

class Box
{
  public:

     double length;
     double breadth;    
     double height;     

     double getVolume(void)
     {
        return length * breadth * height;
     }
};

আপনি যদি চান তবে আপনি স্কোপ রেজুলেশন অপারেটর ব্যবহার করে ক্লাসের বাইরে একই ফাংশনটি সংজ্ঞায়িত করতে পারেন: ::

double Box::getVolume(void)
{
   return length * breadth * height;
}

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

Box myBox;           

myBox.getVolume();  

(থেকে: http://www.tutorialspoint.com/cplusplus/cpp_class_member_funitions.htm ), উভয় উপায় আইনী।

আমি কোনও বিশেষজ্ঞ নই, তবে আমি মনে করি, আপনি যদি একটি ফাইলে কেবল একটি শ্রেণির সংজ্ঞা রাখেন তবে তা আসলে কিছু যায় আসে না।

তবে আপনি যদি অভ্যন্তর শ্রেণির মতো কিছু প্রয়োগ করেন, বা আপনার একাধিক শ্রেণির সংজ্ঞা রয়েছে, তবে দ্বিতীয়টি পড়তে এবং বজায় রাখা শক্ত হবে।


4
আপনি কি সেই লিঙ্ক থেকে প্রাসঙ্গিক সামগ্রীটি আপনার পোস্টের শৃঙ্খলে আনতে পারেন এবং এইভাবে মৃত লিঙ্কগুলির বিরুদ্ধে ভবিষ্যত-প্রমাণকারী? ধন্যবাদ
জাস্টিনজেডাভিজ

2

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


1

শ্রেণীর ভিতরে সংজ্ঞায়িত একটি ফাংশনটি ইনলাইন ফাংশন হিসাবে ডিফল্টরূপে বিবেচিত হয়। আপনার বাইরে আপনার কার্যকারিতাটি সংজ্ঞায়িত করার একটি সহজ কারণ:

শ্রেণীর একজন নির্মাতা ভার্চুয়াল ফাংশনগুলির জন্য পরীক্ষা করে এবং সঠিক ভিটিএবিএল বা ভার্চুয়াল পদ্ধতি টেবিলের দিকে নির্দেশ করার জন্য ভার্চুয়াল পয়েন্টারকে সূচনা করে, বেস শ্রেণীর কনস্ট্রাক্টরকে কল করে এবং বর্তমান শ্রেণীর ভেরিয়েবলকে আরম্ভ করে, সুতরাং এটি আসলে কিছু কাজ করে।

ইনলাইন ফাংশনগুলি ব্যবহৃত হয় যখন ফাংশনগুলি এত জটিল না হয় এবং ফাংশন কলের ওভারহেড এড়ানো হয়। (ওভারহেডে হার্ডওয়্যার স্তরটিতে একটি ঝাঁপ এবং শাখা রয়েছে)) এবং উপরে বর্ণিত হিসাবে, কনস্ট্রাক্টরটিকে ইনলাইন হিসাবে বিবেচনা করা তত সহজ নয়।


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

0

ইনলাইন ফাংশন (যখন আপনি ক্লাসে তাদের ঘোষণা করবেন তখন ফাংশন) প্রতিবার তাদের কল করলে তারা আপনার মূল মেমরি কোডে আটকানো হয়। আপনি যখন ক্লাসের বাইরে ফাংশনটি ঘোষণা করেন, আপনি যখন ফક્શનটি কল করবেন তখন এটি একই মেমরি থেকে আসে। কেন এটি আরও ভাল ts

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