സി++ ക്ലാസുകൾ
ഈ ലേഖനം ദുർഗ്രഹമാം വിധം സാങ്കേതികസംജ്ഞകൾ ഉൾക്കൊള്ളുന്നു. ഈ ലേഖനം കൂടുതൽ ആളുകൾക്ക് പ്രയോജനപ്പെടുന്നതരത്തിൽ പരിഷ്കരിക്കേണ്ടതുണ്ട്. |
class എന്ന സൂചകപദം (keyword) ഉപയോഗിച്ച് ഒരു ഉപഭോക്താവ് തന്നെ ഉണ്ടാക്കുന്ന ഒരു ഡാറ്റാ ടൈപ്പോ അല്ലെങ്കിൽ ദത്തസങ്കേതമോ (data structure) ആണ് സി++'ലെ ക്ലാസ്. ഒരു ക്ലാസ്സിന് അതിലെ അംഗങ്ങളായി ഡാറ്റാ, ഫങ്ക്ഷനുകൾ അഥവാ മെത്തേഡുകൾ എന്നിവ ഉണ്ടാകാം. ഈ അംഗങ്ങളെ private, protected, public
എന്നീ മൂന്നു വ്യത്യസ്ത സമീപനസങ്കേതങ്ങൾ (access modifiers) ഉപയോഗിച്ച് അടയാളപ്പെടുത്താൻ സാധിയ്ക്കും. ഒന്നും അടയാളപ്പെടുത്തിയിട്ടില്ലെങ്കിൽ അത് private
ആണ്. private
(സ്വകാര്യം) എന്നു അടയാളപ്പെടുത്തിയ അംഗങ്ങളെ ക്ലാസിനു പുറത്തു നിന്നും (മറ്റു ക്ലാസ്സുകളോ മെത്തേഡുകളോ) സമീപിയ്ക്കാൻ/ഉപയോഗിയ്ക്കാൻ സാധിയ്ക്കില്ല. protected
(സംരക്ഷിയ്ക്കപ്പെട്ടവ) ആയ അംഗങ്ങളെ ആ ക്ലാസിന്റെ സബ്-ക്ലാസ്സുകൾക്ക് (അതിൽ നിന്നും ഡിറൈവ് ചെയ്യപ്പെട്ട) മറ്റു ക്ലാസ്സുകളിൽ നിന്നും ഉപയോഗിയ്ക്കാൻ സാധിയ്ക്കും. എന്നാൽ പുറത്തു നിന്നുള്ള ക്ലാസ്സുകളിൽ നിന്നും പറ്റില്ല. public
(പൊതുവായ) എന്ന് അടയാളപ്പെടുത്തിയ അംഗങ്ങളെ എവിടെ നിന്നു വേണമെങ്കിലും ഉപയോഗിയ്ക്കാം.
ഈ വിവരണം ഉപയോഗിച്ച് പ്രോഗ്രാം ഓടുന്ന വേളയിൽ അതിന്റെ മെമ്മറിയിൽ ഉണ്ടാക്കപ്പെടുന്ന വസ്തുക്കളെ അതിന്റെ ഇൻസ്റ്റൻസുകൾ എന്നു പറയുന്നു. അനൗപചാരികമായി പറഞ്ഞാൽ ഒരു പാചകക്കുറിപ്പ് ആണ് ക്ലാസ് എന്ന വിവരണം. ഇത് വെച്ച് ഉണ്ടാക്കുന്ന കറിയാണ് ഇൻസ്റ്റൻസുകൾ. ഇൻസ്റ്റൻസുകൾക്ക് മാത്രമാണ് അസ്തിത്വം ഉള്ളത്. ഇവയാണ് ഒരു പ്രോഗ്രാമിന്റെ മെമ്മറിയിൽ 'ജീവിയ്ക്കുന്ന' വസ്തുക്കൾ.
struct (സ്ട്രക്ട് അഥവാ സ്ട്രക്ച്ചർ) class (ക്ലാസ്) എന്നിവ തമ്മിലുള്ള വ്യത്യാസങ്ങൾ
തിരുത്തുകസി++'ൽ ഡാറ്റയും മെത്തേഡുകളും നൽകുന്ന വേറൊരു മെക്കാനിസം ആണ് struct
എന്ന സൂചകപദം ഉപയോഗിച്ച് ഉണ്ടാക്കുന്ന സ്ട്രക്ച്ചറുകൾ. ക്ലാസ്സുകളുമായി ഇവയ്ക്കു നേരിയ വ്യത്യാസമേ ഉള്ളൂ. ഒരു ക്ലാസ്സിൽ ഒരംഗത്തിന് സമീപനസങ്കേതങ്ങൾ ഒന്നും അടയാളപ്പെടുത്തിയിട്ടില്ലെങ്കിൽ അത് private
ആയി എടുക്കപ്പെടുന്നു. ഒരു struct
'ൽ സമീപനസങ്കേതങ്ങൾ ഒന്നും ഉപയോഗിച്ചിട്ടില്ലെങ്കിൽ അത് public
ആയി കണക്കാക്കപ്പെടുന്നു.[1]
സഞ്ചയ ക്ലാസുകൾ (aggregate classes)
തിരുത്തുകഉപഭോക്താവ് നിർമിച്ച കോൺസ്ട്രക്ടർ ഇല്ലാതിരിയ്ക്കുക, പ്രൈവറ്റ്/പ്രൊട്ടക്ടഡ് ആയ അംഗങ്ങൾ ഇല്ലാതിരിയ്ക്കുക, ബേസ് ക്ലാസുകൾ ഇല്ലാതിരിയ്ക്കുക, വിർച്വൽ ഫങ്ക്ഷനുകൾ ഇല്ലാതിരിയ്ക്കുക എന്നീ വ്യവസ്ഥകൾ അംഗീകരിയ്ക്കുന്ന ക്ലാസ്സിനെ സഞ്ചയ ക്ലാസ്സ് എന്ന് വിളിക്കുന്നു.[2] ഇത്തരം ഒരു ക്ലാസ് ഒരു ഇനിഷ്യലൈസെർ ലിസ്റ്റ് വെച്ച് തുടങ്ങിവെയ്ക്കാൻ (initialize) സാധിയ്ക്കുന്നതാണ്.[3] താഴെക്കൊടുത്തിരിയ്ക്കുന്ന കോഡ് സി'യിലും സി++'ലും ഒരുപോലെ സാധുവാണ്.
struct C
{
int a;
double b;
};
struct D
{
int a;
double b;
C c;
};
// C എന്ന ടൈപ്പിൽ ഉള്ള ഒരു ഒബ്ജെക്ടിനെ ഇനിഷ്യലൈസെർ ലിസ്റ്റ് വച്ചു തുടങ്ങിവയ്ക്കുക
C c = {1, 2.0};
// ഇനിഷ്യലൈസെർ ലിസ്റ്റുകൾ ഒന്നിനുള്ളിൽ മറ്റൊന്നായി വരാം
D d = {10, 20.0, {1, 2.0}};
പി.ഓ.ഡി സ്ട്രക്ടുകൾ (POD അഥവാ plain old data object struct)
തിരുത്തുകസി സ്ട്രക്ട് പോലെ ഉണ്ടാക്കിയെടുക്കാവുന്ന സി++ ക്ലാസ്സുകൾ ആണ് പി.ഓ.ഡി സ്ട്രക്ടുകൾ.[4] സി++'ലെ തന്നിരിയ്ക്കുന്ന ടൈപ്പുകൾ (int
, char
തുടങ്ങിയവ) പോലെ തന്നെ ഉപയോഗിയ്ക്കാൻ പറ്റുന്ന ഒരു ഉപഭോക്താവ് ഉണ്ടാക്കിയെടുത്ത ക്ലാസുകൾ ആണ് പി. ഓ. ഡി. ടൈപ്പുകൾ. ഇത്തരം ഒരു ക്ലാസ്സിൽ വളരെ അടിസ്ഥാനപരമായ ക്ലാസ്സുകളുടെ ഡാറ്റാ ചരങ്ങൾ മാത്രമേ അംഗങ്ങളായി ഉണ്ടാകൂ.
വിളംബരവും (declaration) ഉപയോഗവും
തിരുത്തുകസി++ ക്ലാസ്സുകളിൽ പല തരത്തിലുള്ള അംഗങ്ങൾ ഉണ്ടായിരിയ്ക്കും. ഇത് ഡാറ്റാചരങ്ങൾ (variables) ആകാം, ഫങ്ക്ഷനുകൾ അല്ലെങ്കിൽ മെത്തേഡുകൾ ആകാം, കോൺസ്ട്രക്ക്ടറുകളാകാം, ഡിസ്ട്രക്ടറുകളാകാം. ഈ അംഗങ്ങളെ എവിടെ നിന്നൊക്കെ സമീപിയ്ക്കാം എന്നത് ഒരു സമീപനസങ്കേതം ഉപയോഗിച്ച് അടയാളപ്പെടുത്താൻ സാധിയ്ക്കും. ഇത്തരം ഒരു സമീപനസങ്കേതത്തിനു ശേഷം വരുന്ന എല്ലാ അംഗങ്ങൾക്കും ഈ സമീപന രീതി ബാധകമാണ്. ഒരു ക്ലാസ്സിന് മറ്റൊരു ക്ലാസ്സിൽ നിന്നും ഇൻഹെറിറ്റ് ചെയ്യാനും സാധിയ്ക്കും.
ആഗോള ക്ലാസ്സുകളും പ്രാദേശിക ക്ലാസ്സുകളും (global and local classes)
തിരുത്തുകഒരു പ്രോഗ്രാമിലെ എല്ലാ ഫങ്ക്ഷനുകളുടെയും പുറത്തു വിളംബരം ചെയ്യപ്പെട്ട ഒരു ക്ലാസ്സിനെ ആഗോള ക്ലാസ് എന്നു വിളിയ്ക്കുന്നു. ഇത്തരം ഒരു ക്ലാസ് ഉപയോഗിച്ച് ആ പ്രോഗ്രാമിൽ എവിടെ നിന്നും ഒബ്ജക്റ്റുകൾ അഥവാ ഇൻസ്റ്റൻസുകൾ ഉണ്ടാക്കാൻ സാധിയ്ക്കുന്നതാണ്. എന്നാൽ ഒരു ഫങ്ക്ഷന്റെ ഉള്ളിലും ഒരു ക്ലാസ് വിളംബരം ചെയ്യാൻ സാധിയ്ക്കുന്നതാണ്. ഇത്തരം ക്ലാസ്സുകളെ പ്രാദേശിക ക്ലാസുകൾ എന്നു വിളിയ്ക്കുന്നു. പ്രാദേശിക ക്ലാസ്സുകളെ അവ വിളംബരം ചെയ്യപ്പെട്ട സ്കോപിനുള്ളിൽ നിന്നു മാത്രമേ ഉപയോഗിയ്ക്കാൻ സാധിയ്ക്കൂ.
ക്ലാസ് വിളംബരവും ഡാറ്റാ ചരങ്ങളും
തിരുത്തുക class
അല്ലെങ്കിൽ struct
എന്നീ സൂചകപദങ്ങൾ ഉപയോഗിച്ചാണ് ഒരു ക്ലാസ് വിളംബരം ചെയ്യപ്പെടുന്നത്.
struct person
{
string name;
int age;
};
|
class person
{
public:
string name;
int age;
};
|
മുകളിൽ കൊടുത്തിരിയ്ക്കുന്ന രണ്ടു വിവരണങ്ങളും ഒരേ കാര്യം തന്നെയാണ് ചെയ്യുന്നത്. person
എന്ന ടൈപ്പിൽ ഉള്ള ഒബ്ജക്റ്റുകൾക്ക് പൊതു സമീപനത്തിനുള്ള name
, age
എന്നീ രണ്ടു ഡാറ്റാ ചരങ്ങൾ ഉണ്ടായിരിയ്ക്കും എന്നതാണ് ഈ വിവരണത്തിന്റെ അർത്ഥം. അർധവിരാമവും { അടയാളവും അത്യാവശ്യമാണ്.
ഇതിൽ ഏതെങ്കിലും ഒരു വിവരണത്തിനു ശേഷം താഴെ കൊടുത്തിരിയ്ക്കുന്നതു പോലെ person
ക്ലാസ് ഉപയോഗിച്ച് പുതിയ ഡാറ്റാ ചരങ്ങൾ ഉണ്ടാക്കിയെടുക്കാൻ പറ്റുന്നതാണ്:
#include <iostream>
#include <string>
class person
{
public:
string name;
int age;
};
int main()
{
person a, b;
a.name = "Calvin";
b.name = "Hobbes";
a.age = 30;
b.age = 20;
std::cout << a.name << ": " << a.age << std::endl;
std::cout << b.name << ": " << b.age << std::endl;
return 0;
}
ഈ കോഡ് ഓടിച്ചു നോക്കിയാൽ താഴെ കാണുന്ന ഔട്ട്പുട്ട് കിട്ടും.
Calvin: 30 Hobbes: 20
ഒരു ക്ലാസ്സിന്റെ അംഗങ്ങളായ മെത്തേഡുകൾ
തിരുത്തുക
സി++ ക്ലാസിലെയും സ്ട്രക്ക്ച്ചറിലെയും പ്രധാന അംഗങ്ങളാണ് മെത്തേഡുകൾ. ഈ മെത്തേഡുകൾക്ക് ആ ക്ലാസ്സിലെ ഏതു ഡാറ്റാ ചരത്തെയും (private
എന്നോ public
എന്നോ വ്യത്യാസമില്ലാതെ) ഉപയോഗിയ്ക്കാൻ സാധിയ്ക്കുന്നതാണ്. സ്റ്റാറ്റിക് (static
) അല്ലാത്ത മെത്തേഡുകളിൽ നിന്ന് this
എന്ന സൂചകപദം ഉപയോഗിച്ചാൽ ഏതു ഒബ്ജെക്റ്റിൻമേലാണോ ഈ മെത്തേഡ് വിളിച്ചത് ആ ഒബ്ജെക്ടിന്റെ പോയിന്റർ ഉപയോഗിയ്ക്കുന്നതിനു തുല്യമാണ്. കംപൈലർ മെഷീൻ കോഡ് ഉണ്ടാക്കുമ്പോൾ ഇത്തരം മെത്തേഡുകളിലേയ്ക്ക് എപ്പോഴും ഈ ഒബ്ജെക്ടിന്റെ പോയിന്റർ പ്രോഗ്രാമർ പ്രത്യേകിച്ച് എടുത്തു പറയാതെ തന്നെ പാസ് ചെയ്യുന്നതായിരിയ്ക്കും.[5] മുകളിലെ person
ഉദാഹരണം വീണ്ടും എടുക്കുക:
class person
{
std::string name;
int age;
public:
person() : age(5) { }
void print() const;
};
void person::print() const
{
std::cout << name << ":" << age << std::endl;
/* "name", "age" എന്നിവ അംഗങ്ങളായ ഡാറ്റാ ചരങ്ങൾ ആണ്. "this" എന്ന സൂചകപദം ഉപയോഗിച്ചാൽ ഏത് ഒബ്ജെക്ടിൽ ആണോ ഈ മെത്തേഡ് വിളിക്കപ്പെട്ടത് അതിന്റെ പോയിന്റർ കിട്ടും.
*/
}
മുകളിലത്തെ ഉദാഹരണത്തിൽ print()
എന്ന മെത്തേഡ് ക്ലാസ്സിന്റെ ഉള്ളിൽ തന്നെ വിളംബരം ചെയ്യപ്പെട്ടിരിയ്ക്കുന്നു. എന്നാൽ ഇതിന്റെ വിവരണം (definition) ക്ലാസിനു പുറത്താണ്. ഇങ്ങനെ ചെയ്യുമ്പോൾ മെത്തേഡിന് മുന്നിൽ ക്ലാസ്സിന്റെ പേരും ::
എന്ന ചിഹ്നവും ഇടണം. name
ഉം age
ഉംപ്രൈവറ്റ് ആയും print()
എന്ന മേത്തോട് പബ്ലിക് ആയും വിളംബരം ചെയ്യപ്പെട്ടിരിയ്ക്കുന്നു.
ഒരു ഒബ്ജക്റ്റ് ഉപയോഗിച്ച് ഈ print()
, എന്ന ഫങ്ക്ഷനെ വിളിക്കാൻ സാധിയ്ക്കും:
a.print();
b.print();
ഇവിടെ ആദ്യത്തെ വരിയിലെ മെത്തേഡ് ഓടുമ്പോൾ a
എന്ന ഒബ്ജെക്ടിലെ അംഗങ്ങളായ ഡാറ്റാ ചരങ്ങളാണ് പ്രിന്റ് ചെയ്യപ്പെടുക. രണ്ടാമത്തെ വരി ഓടുമ്പോൾ b
എന്ന ഒബ്ജെക്ടിലേതും.
മുകളിൽ കാണിച്ച പോലെ ഒരു ക്ലാസ്സിലെ മെത്തേഡുകളുടെ വിളംബരവും വിവരണവും സാധാരണയായി വേറെ വേറെ ആക്കി വ്യത്യസ്ത ഫയലുകളിലായാണ് സൂക്ഷിച്ചു വെയ്ക്കാറ്. ഒരു ക്ലാസ്സിന്റെ വിളംബരത്തെ അതിന്റെ ഇന്റർഫേസ് എന്നും വിളിയ്ക്കാറുണ്ട്. സാധാരണ ഈ ക്ലാസ്സിനെ ഉപയോഗിയ്ക്കുന്ന മറ്റു പ്രോഗ്രാമ്മുകൾക്കും ക്ലാസ്സുകൾക്കും ഈ ഇന്റർഫേസ് മാത്രം കണ്ടാൽ മതിയാകും. അതിനാൽ ഈ ഇന്റർഫേസിനെ ഒരു ഹെഡർ ഫയലിൽ ആക്കി സൂക്ഷിയ്ക്കുന്നു. ഈ ക്ലാസ്സിന്റെ വിവരണം അഥവാ ഇമ്പ്ളെമെന്റഷൻ വേറെ ഒരു സോഴ്സ് ഫയലിൽ ആണ് സൂക്ഷിയ്ക്കാറ്.
ഇൻഹെറിറ്റൻസ്
തിരുത്തുകഒരു ക്ലാസ്സിനെ മെമ്മറിയിൽ എങ്ങനെ വെയ്ക്കണം എന്നത് സി++ സ്റ്റാൻഡേർഡ് നിഷ്കർഷിയ്ക്കാറില്ല. ഇത് കംപൈലർ ഉണ്ടാക്കുന്നവരുടെ സ്വാതന്ത്ര്യത്തിനു വിട്ടുകൊടുത്തിരിയ്ക്കുകയാണ്. സാധാരണയായി ഒരു ക്ലാസ്സിൽ നിന്നും മറ്റൊന്ന് ഇൻഹെറിറ്റ് ചെയ്യുമ്പോൾ രണ്ടു ക്ലാസ്സിലെ ഡാറ്റ ചരങ്ങളും മെമ്മറിയിൽ ഒന്നിനു പിറകെ മറ്റൊന്നായി വെയ്ക്കുകയാണ് ചെയ്യുക.ഇങ്ങനെ ചെയ്യുകയാണെങ്കിൽ ബേസ് ക്ലാസ്സിന്റെ ഒരു പോയിന്റർ വെച്ച് സൂപ്പർ ക്ലാസ്സിനെ ഉപയോഗിയ്ക്കാൻ എളുപ്പമാകും.
താഴെ കൊടുത്തിരിയ്ക്കുന്ന ഉദാഹരണം ശ്രദ്ധിയ്ക്കുക
class P
{
int x;
};
class C : public P
{
int y;
};
P
യുടെ ഒരു ഒബ്ജെക്ടിലേയ്ക്ക് ചൂണ്ടുന്ന P* p
എന്നൊരു പോയിന്റർ ഉണ്ടെന്നിരിയ്ക്കട്ടെ. ഇതിന്റെ മെമ്മറി ക്രമീകരണം (memory layout) താഴെ കാണുന്നത് പോലെയായിരിയ്ക്കും:
+----+ |P::x| +----+ ↑ p
ഇനി ഇത് C
യുടെ ഒബ്ജക്റ്റ് ആണെങ്കിൽ താഴെ കാണുന്നത് പോലെ ഇരിയ്ക്കും:
+----+----+ |P::x|C::y| +----+----+ ↑ p
അതിനാൽ P
എന്ന ക്ലാസ്സിന്റെ ഒബ്ജെക്ടിന്മേൽ പ്രവർത്തിയ്ക്കുന്ന ഒരു പോയിന്റർ ഉണ്ടെങ്കിൽ C
എന്ന ടൈപ്പിലുള്ള ഒബ്ജെക്ടിന്റെ ഉള്ളിലുള്ള P
യുടെ ഡാറ്റാ ചരങ്ങളെയും അതിന് സമീപിയ്ക്കാൻ സാധിയ്ക്കും. എന്നാൽ ഇത്തരത്തിൽ സി++ ഭാഷ എങ്ങനെ ഇമ്പ്ളേമെന്റ് ചെയ്തിരിയ്ക്കുന്നു എന്നതിനെ അടിസ്ഥാനമാക്കി പ്രോഗ്രാമുകൾ എഴുതുന്നത് ആശാസ്യമല്ല. അതിനാൽ തുടങ്ങിയ ടൈപ്പ് കോൺവെർഷൻ ഓപ്പറേറ്ററുകൾ ഉപയോഗിച്ചാണ് ഒരു ടൈപ്പ് പോയിന്ററിനെ മറ്റൊരു ടൈപ്പ് അയക്കേണ്ടത്.
ഒരു ക്ലാസ് രണ്ടു വ്യത്യസ്ത ക്ലാസ്സുകളിൽ നിന്നും ഇൻഹെറിറ്റ് ചെയ്യുന്ന അവസ്ഥയിൽ ഇത് വളരെ സങ്കീർണമാകും.
ഓവർലോഡഡ് ഓപ്പറേറ്ററുകൾ
തിരുത്തുകസി++'ൽ അടിസ്ഥാന ഗണിതക്രിയകളെ സൂചിപ്പിയ്ക്കുന്ന ഓപ്പറേറ്ററുകളായ + - * /
എന്നിവ ഓവർലോഡ് ചെയ്തു വേറെ തരത്തിൽ എഴുതിയെടുക്കാൻ സാധിയ്ക്കുന്നതാണ്.
എന്നാൽ ഇങ്ങനെ ചെയ്യുമ്പോൾ ഒരു ഓപ്പറേറ്ററിന്റെ അടിസ്ഥാന അർത്ഥം മാറിപ്പോകാത്ത വിധത്തിൽ എഴുതണം എന്നാണ് കീഴ്വഴക്കം. പക്ഷെ ഈ കീഴ്വഴക്കം തെറ്റിച്ചു കോഡ് എഴുതിയാലും പ്രത്യേകിച്ച് കുഴപ്പം ഒന്നും സംഭവിയ്ക്കില്ല. കംപൈലർ അത് സാധാരണ പോലെ കമ്പൈൽ ചെയ്യുകയും ഉദ്ദേശിച്ച പോലെ അത് ഓടുകയും ചെയ്യും. ഉദാഹരണത്തിന് താഴെ കൊടുത്തിരിയ്ക്കുന്ന integer
എന്ന ക്ലാസ്സിലെ integer * integer
എന്ന ഓപ്പറേറ്റർ വിളിച്ചാൽ ഒരു ഗുണിതം കിട്ടിയിരിയ്ക്കണം എന്നതാണ് കീഴ്വഴക്കം. എന്നാൽ കോഡ് എഴുതിയിരിയ്ക്കുന്നത് സങ്കലനം ചെയ്യാനും!
struct integer
{
int i;
integer(int j = 0) : i(j) {}
integer operator*(const integer &k) const
{
return integer (i + k.i);
}
};
struct integer
{
int i;
integer(int j = 0) : i(j) {}
integer operator*(const integer &k) const;
};
integer integer::operator*(const integer &k) const
{
return integer(i * k.i);
}
മുകളിൽ കൊടുത്തിരിയ്ക്കുന്ന ഉദാഹരണത്തിൽ ഒരു struct
'നുള്ളിൽ ഒരു മെത്തേഡ് വിളംബരം ചെയ്തിരിയ്ക്കുന്നു. ഇത് നേരത്തെ കണ്ട ഉദാഹരണത്തിലെ, ക്ലാസ്സിനുള്ളിൽ മെത്തേഡ് വിളംബരം ചെയ്തു പുറത്തു വിവരിയ്ക്കുന്ന രീതിയ്ക്ക് സമാനമാണ്. ഇവിടെ ഓപ്പറേറ്ററിന്റെ വിവരണത്തിൽ const
എന്ന സൂചകപദം രണ്ടു പ്രാവശ്യം കൊടുത്തിരിയ്ക്കുന്നത് ശ്രദ്ധിയ്ക്കുക. ആദ്യത്തേത് മെത്തേഡിലേയ്ക്ക് പാസ് ചെയ്യപ്പെടുന്ന ആർഗ്യുമെന്റിന്റെ ടൈപ്പ് സൂചിപ്പിയ്ക്കാനാണ്. ഇത് const integer &k
എന്നതാണ്.ഇതിന്റ അർഥം ഈ ആർഗ്യുമെന്റ് ഡാറ്റാ ചരത്തിന്റെ വില മെത്തേഡിന്റെ ഉള്ളിൽ വെച്ച് ഒരിയ്ക്കലും മാറില്ല എന്നാണ്. രണ്ടാമത്തത് മെത്തേഡിന്റെ അവസാനം കൊടുത്തിരിയ്ക്കുന്ന ആണ്. ഇത് സൂചിപ്പിയ്ക്കുന്നത് ഈ മെത്തേഡ് ഒരിയ്ക്കലും ആ ഒബ്ജെക്ടിലെ ഡാറ്റാ ചരങ്ങളുടെ വില മാറ്റില്ല എന്നാണ്. ഈ രണ്ടു സൂചകങ്ങളും കംപൈലറിനോടും ഉപഭോക്താക്കളോടും ഉള്ള ഒരു ഉറപ്പാണ്.
const integer &k
എന്ന ടൈപ്പ് വിവരണത്തിലെ &
എന്ന ചിഹ്നം സൂചിപ്പിയ്ക്കുന്നത് k എന്ന ഡാറ്റാ ചരം "pass by reference" എന്ന രീതി വഴിയാണ് മെത്തേഡിലേയ്ക്ക് വില പാസ് ചെയ്യുന്നത് എന്നാണ്. അതായത് k
എന്ന ഡാറ്റാ ചരത്തിന്റെ വില വേണമെങ്കിൽ ഈ മെത്തേഡിനുള്ളിൽ നിന്നും മാറ്റാം. പക്ഷെ const
എന്ന് സൂചിപ്പിച്ചിരിയ്ക്കുന്നതുകൊണ്ട് അങ്ങനെ ചെയ്യില്ല എന്നും ഉറപ്പുവരുത്തപ്പെടുന്നു.
ഓവർലോഡ് ചെയ്യാൻ പറ്റുന്ന ദ്വയാങ്കക്രിയകൾ (Binary overloadable operators)
തിരുത്തുകദ്വയാങ്കക്രിയകൾ എന്നാൽ രണ്ടു ആർഗ്യുമെന്റുകൾ ഉള്ള ക്രിയകൾ. ഇത് "operator (something)" എന്ന സൂചകപദം ഉപയോഗിച്ച് ഓവർലോഡ് ചെയ്യാം. ഇവിടെ 'something' എന്നുള്ളത് ക്ലാസ്സിന്റെ ഒരു ഒബ്ജക്റ്റ് ആണ്. രണ്ടാമത്തെ ഒബ്ജക്റ്റ് ഏതു ഒബ്ജെക്റ്റിലാണോ ഈ ഓപ്പറേറ്റർ വിളിയ്ക്കുന്നത് ആ ഒബ്ജക്റ്റ് തന്നെയാണ്.(this
പോയിന്ററിനെ ഓർക്കുക).
മുകളിൽ കൊടുത്ത integer
എന്ന ക്ലാസിന്റെ ഉദാഹരണം ശ്രദ്ധിയ്ക്കുക. ഇതിലെ *
എന്ന ഓപ്പറേറ്റർ ഈ പാറ്റേണിൽ വിവരിയ്ക്കപ്പെട്ടിട്ടുള്ള ഒരു ഓപ്പറേറ്റർ ആണ്. ഇവിടെ k
എന്നത് പുറത്തു നിന്നും വരുന്ന ഒരു ഒബ്ജക്റ്റ് ആണ്. *
എന്ന ഓപ്പറേറ്ററിന്റെ രണ്ടാമത്തെ ആർഗ്യുമെന്റ് ഏതു ഒബ്ജെക്ടിൽ ആണോ ഈ ഓപ്പറേറ്റർ വിളിയ്ക്കുന്നത് അതാണ്. താഴെ കൊടുത്തിരിയ്ക്കുന്ന കോഡ് കാണുക.
integer i = 1;
/* we can initialize a structure variable this way as
if calling a constructor with only the first
argument specified. */
integer j = 3;
/* variable names are independent of the names of the
member variables of the structure. */
integer k = i * j;
cout << k.i << endl;
ഇവിടെ i * j
എന്ന വരിയിൽ i
എന്ന ഒബ്ജെക്ടിന്റെ ഓപ്പറേറ്റർ മെത്തേഡ് ആണ് വിളിക്കപ്പെടുന്നത്. j
എന്നത് പുറത്തുനിന്നും വരുന്ന ഡാറ്റാ ചരം ആകും.
ഇങ്ങനെ ഓവർലോഡ് ചെയ്യാവുന്ന ദ്വയാങ്കക്രിയകൾ താഴെ കൊടുത്തിരിയ്ക്കുന്നവയാണ്:
ഓപ്പറേറ്റർ | സാധാരണ ഉപയോഗം |
---|---|
+ - * / % | അങ്കഗണിത കണക്കുകൂട്ടലുകൾ |
^ & | << >> | ബിറ്റ്കവൈസ് കണക്കുകൂട്ടലുകൾ |
< > == != <= >= | ലോജിക്കൽ താരതമ്യങ്ങൾ |
&& | ലോജിക്കൽ കൺജംഗ്ഷൻ |
|| | ലോജിക്കൽ ഡിസ്ജംഗ്ഷൻ |
+= -= *= /= %= ^= &= |= <<= >>= |
സംയുക്ത വിലകൊടുക്കൽ(Compound assignment) |
, | (no general usage) |
ഓവർലോഡ് ചെയ്യാൻ പറ്റുന്ന ഏകാങ്കക്രിയകൾ(Unary overloadable operators)
തിരുത്തുകരണ്ടു ആർഗ്യുമെന്റുകൾ ഉള്ള ഓപ്പറേറ്ററുകൾ മുകളിൽ കണ്ടല്ലോ. ചിലപ്പോൾ ഒരു ആർഗ്യുമെന്റ് മാത്രമുള്ള ഓപ്പറേറ്ററുകളും വേണ്ടി വരും. ഇവിടെ പാസ് ചെയ്യപ്പെട്ട ആർഗ്യുമെന്റുകൾ ഉണ്ടാകില്ല, ഏത് ഒബ്ജെക്റ്റിലാണോ ഓപ്പറേറ്റർ വിളിയ്ക്കപ്പെടുന്നത് അത് മാത്രമായിരിയ്ക്കും ആർഗ്യുമെന്റ്.
താഴെ കൊടുത്തിരിയ്ക്കുന്നവയാണ് ഉദാഹരണങ്ങൾ:
Operator | General usage | Position of sender |
---|---|---|
+ - | Positive / negative sign | right |
* & | Dereference | right |
! ~ | Logical / bitwise NOT | right |
++ -- | Pre-increment / decrement | right |
++ -- | Post-increment / decrement | left |
ഇത്തരം ഓപ്പറേറ്ററുകളിൽ ഒരു ചെറിയ സങ്കീർണതയുണ്ട്. ഒരു ആർഗ്യുമെന്റ് മാത്രമുള്ളതുകൊണ്ട് അത് വിളിയ്ക്കപ്പെടുന്ന ഒബ്ജക്റ്റ് ഓപ്പറേറ്ററിന്റെ ഇടതുവശത്താണോ വരേണ്ടത് അതോ വലതുവശത്താണോ വരേണ്ടത് എന്നുള്ളത് കൃത്യമായി സൂചിപ്പിയ്ക്കണം. രണ്ടു ആർഗ്യുമെന്റ് ഉള്ളപ്പോൾ ഇത് എളുപ്പമാണ്. വിളിയ്ക്കപ്പെടുന്ന ഒബ്ജക്റ്റ് ഇടത്തും പാസ് ചെയ്യപ്പെടുന്ന ആർഗ്യുമെന്റ് വലത്തും. ഇത് സൂചിപ്പിയ്ക്കാനായി താഴെ കാണുന്ന കീഴ്വഴക്കം ഉപയോഗിയ്ക്കുന്നു. ആദ്യത്തെ അവസ്ഥയിൽ ഒബ്ജക്റ്റ് വലതുവശത്തു വരുന്നു.:
return_type operator@ ()
ആർഗ്യുമെന്റ് (വിളിയ്ക്കപ്പെടുന്ന ഒബ്ജക്റ്റ്) ഇടതുവശത്തു വരണമെങ്കിൽ ഇങ്ങനെ വിവരിയ്ക്കണം:
return_type operator@ (int)
ഇവിടെ @
എന്നത് ഏതു ഓപ്പറേറ്റർ ആണോ അതിനെ സൂചിപ്പിയ്ക്കുന്നു. return_type
എന്നത് ആ ഓപ്പറേറ്ററിൽ നിന്നും എന്ത് വില പുറത്തേയ്ക്ക് കൊടുക്കുന്നു അതിന്റെ ടൈപ്പിനെ (return type) സൂചിപ്പിയ്ക്കുന്നു (int
, bool
, structures തുടങ്ങിയവ.)
int
എന്ന പാരാമീറ്റർ ആർഗ്യുമെന്റ് ഇടതു വശത്താണ് എന്ന് കാണിക്കാനുള്ള ഒരു കീഴ്വഴക്കം മാത്രമാണ്.
കോൺസ്ട്രക്ടർ
തിരുത്തുകഒരു ക്ലാസ്സിന്റെ ഒബ്ജക്റ്റ് ഉണ്ടാക്കുന്ന സമയത്ത് അതിലെ അംഗങ്ങളായിട്ടുള്ള ചരങ്ങൾക്ക് പുറത്തു നിന്നും വിലകൾ കൊടുക്കണമെങ്കിൽ ഒരു കോൺസ്ട്രക്ടർ ഉപയോഗിച്ച് അത് ചെയ്യാവുന്നതാണ്.
person::person(string N, int A)
{
name = N;
age = A;
}
അടിസ്ഥാന കോൺസ്ട്രക്ടർ (Default constructor)
തിരുത്തുകഒരു കോൺസ്ട്രക്ടറിന് ആർഗ്യുമെന്റുകൾ ഒന്നും തന്നെയില്ലെങ്കിൽ അതിനെ അടിസ്ഥാനകോൺസ്ട്രക്ടർ എന്ന് വിളിയ്ക്കുന്നു.
class A { int b;};
//Object created using parentheses
A *a = new A(); //Calls default constructor, and b will be initialized with '0'
//Object created using no parentheses
A *a = new A; // allocate memory, then call default constructor, and b will have value '0'
//Object creation without new
A a; //Just allocate memory, and b will have unknown garbage value
ഡിസ്ട്രക്ടർ (Destructors)
തിരുത്തുകഒരു കോൺസ്ട്രക്ടറിന്റെ വിപരീത ഉപയോഗമാണ് ഒരു ഡിസ്ട്രക്ടറിന് ഉള്ളത്. ഒരു ക്ലാസ്സിന്റെ ഒബ്ജെക്ടിനെ മെമ്മറിയിൽ നിന്നും നീക്കുമ്പോൾ ആ ക്ലാസ്സിലെ ഏതെങ്കിലും ഡാറ്റാ ചരങ്ങൾക്ക് അവസാനമായി എന്തെങ്കിലും ചെയ്യാനുണ്ടെങ്കിൽ ഒരു ഡിസ്ട്രക്ടർ വേണ്ടി വരും. ഉദാഹരണത്തിന് ഒരു ഡാറ്റാ ചരം ഒരു പോയിന്റർ ആണെന്നും ഇത് ക്ലാസ്സിന്റെ ഉപയോഗത്തിൽ എപ്പോളോ ഒരു മെമ്മറി അലോക്കേഷൻ നടത്തി ഉപയോഗിച്ചു എന്ന് കരുതുക. ഈ അംഗം പോയിന്റ് ചെയ്യുന്ന മെമ്മറി എപ്പോളെങ്കിലും ഡി അലൊക്കേറ്റ് ചെയ്തു വൃത്തിയാക്കേണ്ടി വരും. ഇത്തരം പ്രവൃത്തികൾ ഡിസ്ട്രക്ടരിൽ ആണ് ചെയ്യുക.
ഒരു ഡിസ്ട്രക്ടർ ~ എന്ന പ്രത്യേക ചിഹ്നം ഉപയോഗിച്ചാണ് വിവരിയ്ക്കുക. താഴെ കൊടുത്തിരിയ്ക്കുന്ന ഉദാഹരണം കാണുക..
~person()
{
cout << "I'm deleting " << name << " with age " << age << endl;
}
ക്ലാസ് ടെംപ്ലേറ്റുകൾ (Class templates)
തിരുത്തുകസി++'ൽ ഒരു ക്ലാസ്സിന്റെ വിവരണം ക്ലാസ് ടെംപ്ലേറ്റുകളിൽ നിന്നും ഒരു കംപൈലറിനുതന്നെ ഉണ്ടാക്കിയെടുക്കാൻ സാധിയ്ക്കും. ഇത്തരം ക്ലാസ് ടെംപ്ലേറ്റുകൾ ഒരേ പോലെയുള്ള ക്ലാസ്സുകളുടെ ഒരു കുടുംബത്തെയാണ് പ്രതിനിധീകരിയ്ക്കുന്നത്. കമ്പൈൽ ചെയ്യുന്ന സമയത്ത് ഈ ടെംപ്ലേറ്റിൽ നിന്നും ആവശ്യമുള്ള ക്ലാസ്സിന്റെ കോഡ് കംപൈലർ തന്നെ ഉണ്ടാക്കിയെടുക്കും..
ഇവ കൂടി കാണുക
തിരുത്തുകഅവലംബം
തിരുത്തുക- ↑ ISO/IEC (2003). ISO/IEC 14882:2003(E): Programming Languages - C++ §9 Classes [class] para. 4
- ↑ ISO/IEC (2003). ISO/IEC 14882:2003(E): Programming Languages - C++ §8.5.1 Aggregates [dcl.init.aggr] para. 1
- ↑ ISO/IEC (2003). ISO/IEC 14882:2003(E): Programming Languages - C++ §8.5.1 Aggregates [dcl.init.aggr] para. 2
- ↑ "What's this "POD" thing in C++ I keep hearing about?". Comeau Computing. Archived from the original on 2009-01-19. Retrieved 2009-01-20.
- ↑ "thiscall (C++)". Retrieved 2009-01-26.