সি ফাংশন ঘোষক
প্রথমত, সি ইন সি রয়েছে, A a()ফাংশন ডিক্লেয়ারেশন। উদাহরণস্বরূপ, putcharনিম্নলিখিত ঘোষণা আছে। সাধারণত, এই জাতীয় ঘোষণাগুলি শিরোনাম ফাইলগুলিতে সংরক্ষণ করা হয়, তবে কোনও কাজই আপনাকে ম্যানুয়ালি লিখতে বাধা দেয় না, যদি আপনি জানেন যে ফাংশনটির ঘোষণাপত্রটি কেমন দেখাচ্ছে। আর্গুমেন্টের নামগুলি ঘোষণায় alচ্ছিক, তাই আমি এই উদাহরণে এটি বাদ দিয়েছি।
int putchar(int);
এটি আপনাকে এই জাতীয় কোড লিখতে দেয়।
int puts(const char *);
int main() {
puts("Hello, world!");
}
সি আপনাকে ফাংশন কলের মতো দেখতে দুর্দান্ত পঠনযোগ্য সিনট্যাক্স সহ ফাংশনগুলি যুক্তি হিসাবে হিসাবে ফাংশনগুলি সংজ্ঞায়িত করতে দেয় (ভাল, এটি পঠনযোগ্য, যতক্ষণ আপনি ফাংশনে কোনও পয়েন্টার ফিরিয়ে দেবেন না)।
#include <stdio.h>
int eighty_four() {
return 84;
}
int output_result(int callback()) {
printf("Returned: %d\n", callback());
return 0;
}
int main() {
return output_result(eighty_four);
}
যেমনটি আমি উল্লেখ করেছি, সি হেডার ফাইলগুলিতে যুক্তির নাম বাদ দেওয়ার অনুমতি দেয়, সুতরাং output_resultহেডার ফাইলটিতে এটির মতো দেখাবে।
int output_result(int());
কনস্ট্রাক্টরে একটি যুক্তি
তুমি কি তাকে চিনতে পারো না? ঠিক আছে, আমি আপনাকে স্মরণ করিয়ে দিন।
A a(B());
হ্যাঁ, এটি ঠিক একই ফাংশন ঘোষণা। Aহয় int, aহয় output_resultএবং Bহয়int ।
আপনি সহজেই সি ++ এর নতুন বৈশিষ্ট্যগুলির সাথে সি এর একটি বিরোধ লক্ষ্য করতে পারেন। নির্ভুলভাবে বলতে গেলে, নির্মাতারা শ্রেণীর নাম এবং প্রথম বন্ধনী এবং ()পরিবর্তে পরিবর্তিত ডিক্লেয়ারেশন সিনট্যাক্স =। ডিজাইনের মাধ্যমে, সি ++ সি কোডের সাথে সামঞ্জস্যপূর্ণ হওয়ার চেষ্টা করে, এবং তাই এটি এই ক্ষেত্রে মোকাবেলা করতে হবে - এমনকি বাস্তবে কেউ পাত্তা না দিলেও। অতএব, পুরানো সি বৈশিষ্ট্যগুলির নতুন সি ++ বৈশিষ্ট্যগুলির চেয়ে অগ্রাধিকার রয়েছে। ঘোষণার ব্যাকরণটি নতুন সিনট্যাক্সের সাথে প্রত্যাবর্তনের আগে, নামটিকে ফাংশন হিসাবে মিলানোর চেষ্টা করে() ব্যর্থ হলে এটির ।
যদি এই বৈশিষ্ট্যগুলির মধ্যে একটির অস্তিত্ব না থাকে বা অন্যরকম সিনট্যাক্স থাকে (যেমন {} সি ++ 11 এর মতো), তবে এই সমস্যাটি একটি যুক্তির মাধ্যমে সিনট্যাক্সের জন্য কখনও ঘটেনি।
এখন আপনি জিজ্ঞাসা করতে পারেন কেন A a((B()))কাজ করে। ঠিক আছে, আসুন output_resultঅকেজো বন্ধনী যুক্ত করুন।
int output_result((int()));
এটি কাজ করবে না। ব্যাকরণটি বন্ধনীতে না থাকার জন্য পরিবর্তনশীল প্রয়োজন।
<stdin>:1:19: error: expected declaration specifiers or ‘...’ before ‘(’ token
তবে সি ++ এখানে স্ট্যান্ডার্ড এক্সপ্রেশন আশা করে। সি ++ এ আপনি নিম্নলিখিত কোডটি লিখতে পারেন।
int value = int();
এবং নিম্নলিখিত কোড।
int value = ((((int()))));
সি ++ প্রত্যাশা প্রত্নতুলীর অভ্যন্তরের অভ্যন্তরের ভিতরে ... ভাল ... এক্সপ্রেশনটি সি প্রকারের বিপরীতে যেমন প্রত্যাশা করে। প্যারেন্টিসিস এখানে কিছু বোঝায় না। যাইহোক, অকেজো বন্ধনী tingোকানোর মাধ্যমে, সি ফাংশন ঘোষণাটি মিলছে না এবং নতুন সিনট্যাক্সটি সঠিকভাবে মিলে যেতে পারে (যা কেবল কোনও এক্সপ্রেশন যেমন প্রত্যাশা করে যেমন2 + 2 )।
কনস্ট্রাক্টরে আরও যুক্তি
অবশ্যই একটি যুক্তি চমৎকার, কিন্তু দুটি সম্পর্কে কি? এটি এমন নয় যে নির্মাণকারীদের কেবল একটি যুক্তি থাকতে পারে। অন্তর্নির্মিত ক্লাসগুলির মধ্যে একটি যা দুটি তর্ক করেstd::string
std::string hundred_dots(100, '.');
এটি সমস্ত ভাল এবং সূক্ষ্ম (প্রযুক্তিগতভাবে, এটি সবচেয়ে ভেক্সিং পার্স হতে পারে যদি এটি হিসাবে লেখা হয় std::string wat(int(), char())তবে আসুন সত্যবাদী হন - কে তা লিখবে? তবে এই কোডটির একটি ভেক্সিং সমস্যা আছে বলে ধরে নেওয়া যাক আপনি ধরে নিতেই হবে প্রথম বন্ধনীতে।
std::string hundred_dots((100, '.'));
বেশ তাই না।
<stdin>:2:36: error: invalid conversion from ‘char’ to ‘const char*’ [-fpermissive]
In file included from /usr/include/c++/4.8/string:53:0,
from <stdin>:1:
/usr/include/c++/4.8/bits/basic_string.tcc:212:5: error: initializing argument 1 of ‘std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ [-fpermissive]
basic_string<_CharT, _Traits, _Alloc>::
^
আমি নিশ্চিত নই কেন জি ++ রূপান্তর charকরার চেষ্টা করে const char *। যে কোনও উপায়ে, কনস্ট্রাক্টরকে টাইপের মাত্র একটি মান দিয়ে ডাকা হত char। কোনও ওভারলোড নেই যার এক প্রকারের যুক্তি রয়েছে char, তাই সংকলক বিভ্রান্ত। আপনি জিজ্ঞাসা করতে পারেন - আর্গুমেন্টটি টাইপের চরের কেন?
(100, '.')
হ্যাঁ, , এখানে একটি কমা অপারেটর। কমা অপারেটর দুটি আর্গুমেন্ট নেয় এবং ডান দিকের যুক্তি দেয়। এটি সত্যিই দরকারী নয়, তবে এটি আমার ব্যাখ্যাটির জন্য পরিচিত to
পরিবর্তে, সর্বাধিক ভেক্সিং পার্স সমাধান করার জন্য, নিম্নলিখিত কোডটি প্রয়োজন।
std::string hundred_dots((100), ('.'));
আর্গুমেন্টগুলি প্রথম অভিব্যক্তি নয়, বন্ধনীতে রয়েছে। প্রকৃতপক্ষে, কেবলমাত্র একটির এক্সপ্রেশনগুলির বন্ধনীতে থাকা দরকার, কারণ এটি সি ++ বৈশিষ্ট্যটি ব্যবহার করতে সি ব্যাকরণ থেকে সামান্য বিরতিই যথেষ্ট। বিষয়গুলি আমাদের শূন্য আর্গুমেন্টের পর্যায়ে নিয়ে আসে।
কনস্ট্রাক্টরে জিরো আর্গুমেন্ট
eighty_fourআমার ব্যাখ্যাতে আপনি হয়ত ফাংশনটি লক্ষ্য করেছেন ।
int eighty_four();
হ্যাঁ, এটি সবচেয়ে ভেক্সিং পার্স দ্বারাও প্রভাবিত হয়। এটি একটি বৈধ সংজ্ঞা এবং আপনি সম্ভবত শিরোনাম ফাইলগুলি তৈরি করেছেন (এবং আপনার হওয়া উচিত) one বন্ধনী যুক্ত করা এটি ঠিক করে না।
int eighty_four(());
কেন যে এত? ভাল, ()একটি অভিব্যক্তি নয়। সি ++ এ আপনাকে প্রথম বন্ধনীগুলির মধ্যে প্রকাশ করতে হবে। আপনি auto value = ()সি ++ এ লিখতে পারবেন না , কারণ এর ()অর্থ কিছু নেই (এবং খালি টিপলের মতো হলেও (পাইথন দেখুন) এটি একটি যুক্তি হবে, শূন্য নয়)। কার্যত তার মানে আপনি সি ++ 11 এর {}সিনট্যাক্স ব্যবহার না করে শর্টহ্যান্ড সিনট্যাক্স ব্যবহার করতে পারবেন না , কারণ বন্ধনীতে কোনও মত প্রকাশ নেই এবং ফাংশন ঘোষণার জন্য সি ব্যাকরণ সর্বদা প্রযোজ্য হবে।
(B())এটি কেবলমাত্র একটি সি ++ এক্সপ্রেশন, এর চেয়ে বেশি কিছুই নয়। এটি কোনও ধরণের ব্যতিক্রম নয়। এটি কেবলমাত্র পার্থক্যটি হ'ল এটি সম্ভবত কোনও ধরণের হিসাবে পার্স করার কোনও উপায় নেই এবং তাই এটি নয়।