Constructor
Objenin oluşturulma aşamasında çalışan ve gerekli atamalarla işlemleri yapan fonksiyondur. Sınıfın member variable’larına constructor içerisinde ilk değer ataması yapılır. C++ 11 den itibaren ilk değer atamısını constructor kullanmadan yapabiliriz:
class Air{
float temperature{321};
};
Constructor delegation
Bir constructor’den başka bir constructor’ı çağırıp kod tekrarını minimize etmek amaçlanır.
class Air {
float temperature;
float velocity;
float pressure;
public:
Air(){
temperature = 321;
velocity = 0;
pressure = 223;
}
Air(float temperature) : Air() {
this->temperature = temperature;
}
};
Constructor types
- Default Constructor
- Parameterized Constructor
- Copy Constructor
- Move Constructor
- https://learn.microsoft.com/en-us/cpp/cpp/constructors-cpp?view=msvc-170
- https://learn.microsoft.com/en-us/cpp/cpp/delegating-constructors?view=msvc-170
Copy Constructor
Var olan bir nesneden başka bir nesneyi initialize ederken kullanılır. Tıpkı default constructor gibi implicit olarak compiler tarafından sınıfa eklenir. Lakin bazı durumlarda nesnenin istediğimiz gibi kopyalanması için kendimizi yazarız.
class Air {
Air(const Air& other); // copy constructor
};
int main(){
Air a1;
Air a2(a1); // copy constructor called
Air a3 = a1; // also copy constructor called because this is not an assignment
// fonksiyon çağrılarında ve returnlerde copy constructor çağrılabilir.
}
Assignment Operator
x = y; // x nesnesinin assignment operatörü çağrılır.
// birden fazla atama operatörü varsa aşağıdaki mantıkla çalışır
x = y = z;
x = (y = z);
// Atama operatörü:
Air& operator =(const Air& air){
velocity = air.velocity;
temperatture = air.temperature;
return *this;
}
Synthesized Member Functions
The six special members functions described above are members implicitly declared on classes under certain circumstances:
Member function | implicitly defined: | default definition: |
---|---|---|
Default constructor | if no other constructors | does nothing |
Destructor | if no destructor | does nothing |
Copy constructor | if no move constructor and no move assignment | copies all members |
Copy assignment | if no move constructor and no move assignment | copies all members |
Move constructor | if no destructor, no copy constructor and no copy nor move assignment | moves all members |
Move assignment | if no destructor, no copy constructor and no copy nor move assignment | moves all members |
Shallow and Deep Copying
- Eğer sadece öteki nesnenin pointer adresi kopyalanırsa bu shallow copy olur.
- Bellekte yeni bir memory allocate edilip data kopyalanırsa bu deep copy olur.
class MyString {
char * data;
int size;
public:
MyString(string str){
size = str.size();
data = new char[size];
copy(str.begin(), str.end(), data);
}
MyString(const MyString& str) {
size = str.size;
data = new char[size];
copy(str.data, str.data + size, data);
}
MyString& operator = (const MyString& str) {
if (&str != this) { // check for self-assignment
delete[] data;
size = str.size;
data = new char[size];
copy(str.data, str.data + size, data);
}
return *this;
}
~MyString() {
delete[] data;
}
};
Rule of Three
If a class requires a user-defined destructor, a user-defined copy constructor, or a user-defined copy assignment operator, it almost certainly requires all three.
https://en.cppreference.com/w/cpp/language/rule_of_three
Copy Ellision
In C++ computer programming, copy elision refers to a compiler optimization technique that eliminates unnecessary copying of objects.
https://en.wikipedia.org/wiki/Copy_elision
Conversion Operators
class Air {
int i{};
public:
Air(int n) :i{ n } {}
//explicit Air(int n) :i{ n } {}
operator int() const { return i; }
explicit operator float() const { return 3.5; }
};
int main() {
Air air = 7; // implicit constructor
// implicit conversion & explicit conversion
cout << air + 3 << endl; // 10
cout << static_cast<float>(air) << endl; // 3.5
}
Default and Delete Keywords
- Default: default, copy, gibi constructorları sentezlemek için kullanılır.
- Delete: constructor’ı siler/kullanmayı engeller. Tıpkı bir constructor’ı private yapmak gibi
struct noncopyable
{
noncopyable() =default;
noncopyable(const noncopyable&) =delete;
noncopyable& operator=(const noncopyable&) =delete;
};
The Friend Keyword
Sınıfın, member fonksiyonu olmayan fonksiyon ve diğer sınıflara; private memberlarına erişime izin vermesidir. Yani bir sınıfın friend fonksiyonu o sınıfa ait olmasa da, o sınıfın private member’larına erişebilir.
class M{
friend class F; // Introduces F but doesn't define it
friend void ChangePrivate( Point & );
};
void ChangePrivate ( Point &i ) { i.m_i++; }
class F {};
Member and Non-member Operators
If you define your operator overloaded function as member function, then the compiler translates expressions like s1 + s2
into s1.operator+(s2)
. That means, the operator overloaded member function gets invoked on the first operand. That is how member functions work!
But what if the first operand is not a class? There’s a major problem if we want to overload an operator where the first operand is not a class type, rather say double
. So you cannot write like this 10.0 + s2
. However, you can write operator overloaded member function for expressions like s1 + 10.0
.
To solve this ordering problem, we define operator overloaded function as friend
IF it needs to access private
members. Make it friend
ONLY when it needs to access private members. Otherwise simply make it non-friend non-member function to improve encapsulation!
class Sample
{
public:
Sample operator + (const Sample& op2); //works with s1 + s2
Sample operator + (double op2); //works with s1 + 10.0
//Make it `friend` only when it needs to access private members.
//Otherwise simply make it **non-friend non-member** function.
friend Sample operator + (double op1, const Sample& op2); //works with 10.0 + s2
}
Read these :
A slight problem of ordering in operands
How Non-Member Functions Improve Encapsulation
Prefix and Postfix Operators
// prefix
++p;
// equivalent of the prefix operator
p = p + 1;
return p;
// postfix;
p++;
// eqivalent of the postfix operator
temp = p;
p = p + 1;
return temp;
// operator overloading of prefix & postfix
Air& operator ++(){ // prefix
++var;
return *this;
}
Air operator ++(int t){ // postfix (int is a dummy variable)
Air temp(*this);
++var;
return temp;
}
Function Call Operator
Bir nesneyi bir fonksiyon gibi kullanabilmeyi sağlar.
class Functor
{
public:
int operator()(int a, int b)
{
return a < b;
}
};
int main()
{
Functor f;
int a = 5;
int b = 7;
int ans = f(a, b);
}
https://learn.microsoft.com/en-us/cpp/standard-library/function-objects-in-the-stl?view=msvc-170
Printing Out Class Member Data
class Date{
// ...
friend ostream& operator<<(ostream& os, const Date& dt);
};
ostream& operator<<(ostream& os, const Date& dt)
{
os << dt.mo << '/' << dt.da << '/' << dt.yr;
return os;
}
Leave a Reply