জাভার ফাইনাল বনাম সি ++ এর কনস্ট


151

সি ++ প্রোগ্রামারদের জন্য জাভা টিউটোরিয়াল বলছেন (হাইলাইট আমার নিজের নয়) যে:

মূলশব্দ ফাইনালটি সি ++ তে প্রায় সমান

এই প্রসঙ্গে "মোটামুটি" এর অর্থ কী? তারা কি ঠিক এক নয়?

পার্থক্য কি, যদি কোন?

উত্তর:


195

সি ++ এ সদস্য ফাংশন চিহ্নিত করার constঅর্থ এটি constউদাহরণ হিসাবে বলা যেতে পারে । জাভা এর সমতুল্য নয়। উদাহরণ:

class Foo {
public:
   void bar();
   void foo() const;
};

void test(const Foo& i) {
   i.foo(); //fine
   i.bar(); //error
}

একবারে জাভাতে একবারগুলি মান নির্ধারণ করা যেতে পারে যেমন:

public class Foo {
   void bar() {
     final int a;
     a = 10;
   }
}

জাভাতে আইনী, তবে সি ++ নয়:

public class Foo {
   void bar() {
     final int a;
     a = 10;
     a = 11; // Not legal, even in Java: a has already been assigned a value.
   }
}

উভয় জাভা এবং সি ++ সদস্যের ভেরিয়েবল যথাক্রমে final/ হতে পারে const। ক্লাসের একটি উদাহরণ নির্মাণের কাজ শেষ হওয়ার পরে এগুলি একটি মান দেওয়া দরকার।

জাভাতে তাদের কনস্ট্রাক্টর শেষ হওয়ার আগে অবশ্যই সেট করতে হবে, এটি দুটি উপায়ে একটির মাধ্যমে অর্জন করা যেতে পারে:

public class Foo {
   private final int a;
   private final int b = 11;
   public Foo() {
      a = 10;
   }
}

সি ++ তে আপনাকে constসদস্যদের একটি মান দেওয়ার জন্য সূচনা তালিকা ব্যবহার করতে হবে :

class Foo {
   const int a;
public:
   Foo() : a(10) {
      // Assignment here with = would not be legal
   }
};

জাভা ফাইনালে অ-ওভারড্রিয়েবল হিসাবে জিনিস চিহ্নিত করতে ব্যবহার করা যেতে পারে। সি ++ (প্রাক-সি ++ 11) এটি করে না। উদাহরণ:

public class Bar {
   public final void foo() {
   }
}

public class Error extends Bar {
   // Error in java, can't override
   public void foo() {
   }
}

তবে সি ++ এ:

class Bar {
public:
   virtual void foo() const {
   }
};

class Error: public Bar {
public:
   // Fine in C++
   virtual void foo() const {
   }
};

এটি ঠিক আছে, কারণ সদস্য ফাংশন চিহ্নিত করার শব্দার্থবিজ্ঞান constআলাদা। (আপনি ওভারলোডও করতে পারেন কেবল constসদস্য ফাংশনগুলির মধ্যে একটিতে থাকলেও ((এছাড়াও নোট করুন যে সি ++ 11 সদস্য ফাংশনগুলিকে চূড়ান্ত চিহ্নিত করার অনুমতি দেয়, সি ++ 11 আপডেট বিভাগটি দেখুন)


সি ++ 11 আপডেট:

সি ++ 11 আসলে finalজাভাতে একই বৈশিষ্ট্যের জন্য অভিন্ন শব্দার্থবিজ্ঞান সহ, উভয় শ্রেণি এবং সদস্য ফাংশন হিসাবে চিহ্নিত করার অনুমতি দেয় : উদাহরণস্বরূপ জাভাতে:

public class Bar {
   public final void foo() {
   }
}

public class Error extends Bar {
   // Error in java, can't override
   public void foo() {
   }
}

এখন ঠিক C ++ 11 এ লিখিত হতে পারে:

class Bar {
public:
  virtual void foo() final;
};

class Error : public Bar {
public:
  virtual void foo() final;
};

আমি এই উদাহরণটি জি ++ 4.7 এর প্রাক-প্রকাশের সাথে সংকলন করতে হয়েছিল। নোট করুন যে এটি constএই ক্ষেত্রে প্রতিস্থাপন করে না , বরং এটি জাভা-জাতীয় আচরণ প্রদান করে যা নিকটতম সমমানের সি ++ কীওয়ার্ডের সাথে দেখা যায় নি। সুতরাং যদি আপনি সদস্য ফাংশন উভয়ই হতে চান finalএবং constআপনি এটি করেন:

class Bar {
public:
  virtual void foo() const final;
};

( এখানে constএবং এর ক্রম finalপ্রয়োজনীয়)।

পূর্বে constসদস্য ফাংশনের প্রত্যক্ষ সমতুল্য ছিল না যদিও virtualসংকলন সময়ে ত্রুটি সৃষ্টি না করে ফাংশন অ- তৈরি করা একটি সম্ভাব্য বিকল্প হতে পারে।

তেমনি জাভা:

public final class Bar {
}

public class Error extends Bar {
}

সি ++ 11 এ পরিণত হয়:

class Bar final {
};

class Error : public Bar {
};

(পূর্বে privateকনস্ট্রাক্টররা সম্ভবত আপনি এটির নিকটতম সি ++ এ পেতে পারেন)

মজার বিষয় হল, প্রাক-সি ++ 11 কোডের সাথে পিছনের দিকে সামঞ্জস্যতা বজায় রাখতে সাধারণভাবে কোনও কীওয়ার্ড final নয় । ( struct final;এটিকে কীওয়ার্ড বানানোর কোডটি কেন ভেঙে যাবে তা দেখতে তুচ্ছ, আইনী সি ++ 98 উদাহরণ নিন )


3
আপনার সেই পদ্ধতিগুলি ভার্চুয়াল করা উচিত; অন্যথায়, আপনি সত্যিই একই জিনিস করছেন না
ব্লুরাজা - ড্যানি প্লেফুঘুফ্ট

1
আপনার শেষ উদাহরণে, আপনার কাছে যা আছে তা আইনী, তবে এটি উল্লেখ করার মতো final int a; a = 10; a = 11;নয় (এটি finalএকটি ভেরিয়েবল সংশোধক হিসাবে উদ্দেশ্য হিসাবে নেওয়া হচ্ছে )) এছাড়াও, চূড়ান্ত সদস্যদের কেবলমাত্র শ্রেণির ঘোষণার সময় বা একবার কনস্ট্রাক্টরে সেট করা যায় ।
কর্সিকা

2
মনে রাখবেন যে সি ++ 0x finalএই সঠিক উদ্দেশ্যে সদস্য ফাংশন ডেকরেটার যুক্ত করে । ভিসি ++ 2005, 2008 এবং 2010 এর sealedপরিবর্তে প্রাসঙ্গিক কীওয়ার্ড ব্যবহার করে ইতিমধ্যে এটি প্রয়োগ করা হয়েছে final
iljarn

@ বিল্ডার্ন-এটি জানা আকর্ষণীয় এবং অন্য একটি অপেক্ষাকৃত ছোট সি ++ 0 এক্স পরিবর্তন যা আমি অবগত ছিলাম না! আমি সম্ভবত লেখার কোথাও একটি ছোট মন্তব্য যুক্ত করব যা ইঙ্গিত করে যে এটি সি ++ 0x এর সাথে পরিবর্তিত হচ্ছে।
ফ্লেক্সো

1
দৃশ্যত লোকেরা এখনও ফলাফল হিসাবে ফাইনালট্রাক্টরের সাথে কোডবেসে এস / কনস্ট / ফাইনাল / জি করে!
ফ্লেক্সো

30

জাভাতে চূড়ান্ত কীওয়ার্ডটি চারটি জিনিসের জন্য ব্যবহার করা যেতে পারে:

  • কোনও শ্রেণি বা পদ্ধতিতে এটি সিল করার জন্য (কোনও সাবক্লাস / ওভাররাইডিং অনুমোদিত নয়)
  • সদস্য ভেরিয়েবলের ঘোষণার জন্য এটি ঠিক একবার সেট করা যেতে পারে (আমি মনে করি এটিই আপনি যা বলছেন)
  • কোনও পদ্ধতিতে ঘোষিত ভেরিয়েবলের উপর, এটি একবারে সেট করা যেতে পারে তা নিশ্চিত করে
  • কোনও পদ্ধতির পরামিতিতে, এটি ঘোষণা করতে যে এটি পদ্ধতির মধ্যে পরিবর্তন করা যায় না

একটি গুরুত্বপূর্ণ বিষয় হ'ল: একটি জাভা চূড়ান্ত সদস্য ভেরিয়েবল অবশ্যই একবার সেট করতে হবে! উদাহরণস্বরূপ, কোনও কনস্ট্রাক্টরে, ক্ষেত্রের ঘোষণা, বা অন্তর্নিদীকরণকারী। (তবে আপনি কোনও পদ্ধতিতে চূড়ান্ত সদস্য পরিবর্তনশীল সেট করতে পারবেন না)।

সদস্যকে পরিবর্তনশীল চূড়ান্ত করার আরেকটি পরিণতি মেমরির মডেলের সাথে সম্পর্কিত, আপনি যদি থ্রেডযুক্ত পরিবেশে কাজ করেন তবে তা গুরুত্বপূর্ণ।


'মেমোরি মডেল' বলতে কী বোঝ? আমি পাই না।
টনি

1
@ টনি: জাভা ভাষার নির্দিষ্টকরণ, অধ্যায় 17.4। মেমোরি মডেল - docs.oracle.com/javase/specs/jls/se8/html/index.html - গুগলস প্রথম হিট
রাল্ফ

27

কোনও constবস্তু কেবল constপদ্ধতিগুলিকে কল করতে পারে এবং এটি সাধারণত অপরিবর্তনীয় বলে মনে করা হয়।

const Person* person = myself;
person = otherPerson; //Valid... unless we declared it const Person* const!
person->setAge(20); //Invalid, assuming setAge isn't a const method (it shouldn't be)

কোনও finalঅবজেক্ট কোনও নতুন অবজেক্টে সেট করা যায় না, তবে তা অপরিবর্তনীয় নয় - কাউকে কোনও setপদ্ধতি কল করতে বাধা দেওয়ার কিছুই নেই ।

final Person person = myself;
person = otherPerson; //Invalid
person.setAge(20); //Valid!

জাভা অপরিবর্তনীয় বস্তু ঘোষণার সহজাত উপায় নেই; আপনি নিজেকে অপরিবর্তনীয় হিসাবে ক্লাস ডিজাইন করতে হবে।

যখন ভেরিয়েবলটি আদিম ধরণের হয়, final/ constএকই কাজ করুন।

const int a = 10; //C++
final int a = 10; //Java
a = 11; //Invalid in both languages

3
এটিও একটি দুর্দান্ত উত্তর, (এখানে অন্য অনেকের মতো)। দুর্ভাগ্যক্রমে, আমি কেবল একটি উত্তর গ্রহণ করতে পারি। :)
উইনউইন

1
নিখুঁত উত্তর!
এডিজে

13

জাভা ফাইনালটি আদিম মানের ধরণের উপর সি ++ কনস্টের সমতুল্য।

জাভা রেফারেন্সের ধরণের সাথে, চূড়ান্ত কীওয়ার্ডটি কনস্ট পয়েন্টারের সমতুল্য ... অর্থাৎ

//java
final int finalInt = 5;
final MyObject finalReference = new MyObject();

//C++
const int constInt = 5;
MyObject * const constPointer = new MyObject();

"চূড়ান্ত কীওয়ার্ডটি কনস্ট পয়েন্টারের সমতুল্য" ভাল করে বলেছে
এডিজে

8

আপনার এখানে ইতিমধ্যে কয়েকটি দুর্দান্ত উত্তর রয়েছে তবে একটি পয়েন্ট যা যুক্তিযুক্ত বলে মনে হয়: constপ্রোগ্রামটির অন্যান্য অংশগুলিকে অবজেক্টের স্থিতি পরিবর্তন করে রোধ করতে সাধারণত সি ++ ব্যবহার করা হয়। যেমন উল্লেখ করা হয়েছে, finalজাভাতে এটি করতে পারে না (আদিমগুলি বাদে) - এটি কেবল রেফারেন্সটিকে অন্য কোনও বস্তুতে পরিবর্তিত হতে বাধা দেয় । তবে আপনি যদি একটি ব্যবহার Collectionকরে থাকেন তবে স্থির পদ্ধতিটি ব্যবহার করে আপনি আপনার অবজেক্টগুলিতে পরিবর্তনগুলি রোধ করতে পারেন

 Collection.unmodifiableCollection( myCollection ) 

এটি এমন একটি Collectionরেফারেন্স দেয় যা উপাদানগুলিতে পঠন-অ্যাক্সেস দেয়, তবে constসি -++ এর মতো কিছুটা হলেও পরিবর্তনের চেষ্টা করা হলে একটি ব্যতিক্রম ছুঁড়ে ফেলে


8

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

প্রথমটির const list<int> melist;সাথে তুলনা করা final List<Integer> melist;তালিকাকে সংশোধন করা অসম্ভব করে তোলে, তবে পরেরটি আপনাকে কেবলমাত্র একটি নতুন তালিকা বরাদ্দ করা থেকে বিরত করে melist


3

নির্দিষ্ট এবং সূক্ষ্ম মাল্টি-থ্রেডিং বৈশিষ্ট্য বাদে ঘোষিত ভেরিয়েবলগুলি ঘোষণার finalসময় আরম্ভ করার প্রয়োজন হয় না!

যেমন জাভাতে এটি বৈধ:

// declare the variable
final int foo;

{
    // do something...

    // and then initialize the variable
    foo = ...;
}

সি ++ এর সাথে লেখা থাকলে এটি বৈধ হবে না const


2

উইকিপিডিয়া অনুসারে :

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

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

2

আমি অনুমান করছি এটি "মোটামুটি" বলে কারণ constআপনি পয়েন্টার, অর্থাৎ ধ্রুবক পয়েন্টার বনাম স্থির বস্তুতে পয়েন্টার সম্পর্কে কথা বলার সময় সি ++ এর অর্থ জটিল হয়ে যায়। যেহেতু জাভাতে কোনও "সুস্পষ্ট" পয়েন্টার finalনেই , তাই এই সমস্যাগুলি নেই।


1

স্যুইচ / কেস স্টেটমেন্টের উদাহরণ দিয়ে আমি কী বুঝলাম তা আমাকে ব্যাখ্যা করতে দিন।

প্রতিটি কেস স্টেটমেন্টের মানগুলি অবশ্যই স্যুইচ মান হিসাবে একই ডেটা টাইপের ধরণের মান সংকলন-কালীন হতে হবে।

নীচের মতো কিছু ঘোষণা করুন (হয় স্থানীয় পদ্ধতি হিসাবে আপনার পদ্ধতিতে, বা আপনার শ্রেণিতে স্ট্যাটিক ভেরিয়েবল হিসাবে (তারপরে এটি স্ট্যাটিক যুক্ত করুন), বা একটি উদাহরণ ভেরিয়েবল।

final String color1 = "Red";

এবং

static final String color2 = "Green";

switch (myColor) { // myColor is of data type String
    case color1:
    //do something here with Red
    break;
    case color2:
    //do something with Green
    break;
}

এই কোডটি color1কোনও শ্রেণি / ইনস্ট্যান্স ভেরিয়েবল এবং স্থানীয় ভেরিয়েবল না হলে সংকলন করবে না । color1স্থির চূড়ান্ত হিসাবে সংজ্ঞায়িত করা হলে এটি সংকলন করবে (তারপরে এটি স্থির চূড়ান্ত পরিবর্তনশীল হয়ে যায়)।

এটি সংকলন না করলে আপনি নিম্নলিখিত ত্রুটি পাবেন

error: constant string expression required

-7

মূল শব্দ "কনস্ট" এর অর্থ আপনার ভেরিয়েবলটি রমে সংরক্ষণ করা হয়েছে (মাইক্রোপ্রসেসরের সাথে)। কম্পিউটারে আপনার ভেরিয়েবলটি র্যাম এরিয়াতে এসেম্বলি কোডের জন্য সংরক্ষণ করা হয় (কেবলমাত্র র‌্যাম পড়ুন)। এর অর্থ হল আপনার পরিবর্তনশীলটি রচনামূলক র‌্যামে অন্তর্ভুক্ত নয়: স্ট্যাটিক মেমরি, স্ট্যাক মেমরি এবং হিপ মেমরি।

"চূড়ান্ত" কীওয়ার্ডটির অর্থ হ'ল আপনার পরিবর্তনশীলটি রচনামূলক র‌্যামে সংরক্ষিত হয়েছে তবে আপনি আপনার সংকলনটি লক্ষ্য করেছেন যে আপনার চলকটি কেবলমাত্র একবার পরিবর্তিত হবে।

//in java language you can use:
static final int i =10;
i =11; //error is showed here by compiler

//the same in C++ the same as follows
int i =10;
const int &iFinal = i;

iFinal = 11; //error is showed here by compiler the same as above

আমি মনে করি, "কনস্ট" পারফরম্যান্সে খারাপ, তাই জাভা এটি ব্যবহার করে না।

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