Copy Constructor Private Alanlara Erişebilir
Bu kural sadece Copy Constructor için değil kendi tipini parametre alan diğer metodlar için de geçerlidir.
Örnek
Şöyle yaparız.
Şöyle yaparız.
Copy constructor imzası her zaman reference almalıdır
Parametre const olabilir veya olmayabilir.
Elimizde şöyle bir kod olsun. Bu koddaki son satır copy constructor yerine template constructor'ı çalıştıyor. Çünkü non-const nesne'yi const yapmak maliyetli, template constructor ise direkt çağrılabiliyor.
Copy constructor ve assignment operatör aynı gibi görünse de birisi yeni nesne oluştururken çağrılır. Diğeri ise mevcut nesne için çağrılır. Aşağıdaki örneklerde yeni bir nesne yaratılıyor
Bir nesne diğer bir nesneye eşitlenerek yaratılırsa copy constructor çağırılır. Örnek:
Assignment operatörünün çağrılıp çağrılmayacağını anlamanın en kolay yolu = işaretinden önce g değişkenin tanımlanıp tanımlanmamış olduğuna bakmak.
Copy Constructor Ne Zaman Üretilmez
Eğer alanlardan bir veya daha fazlasının copy constructor metodu etkinsizleştirişmiş ise üretilmez. Elimizde şöyle bir sınıf olsun.
Copy Constructor'ın Etkinsizleştirilmesi Ancak Move Constructor Kullanılması
Copy constructor etkinsizleştirilse bile move constructor kullanmaya devam etmek isteyebiliriz.
Örnek
Bu durumda şöyle yaparız.
Şöyle yaparız
Bu duruma ne zaman ihtiyaç olur
Örnek 1 :
Bir nesne kopyalanmasın ancak temporary nesneleri de metodlardan dönebilelim istersek kullanırız. Yani şöyle yapmak istersek kullanırız.
Nesnemizi geçici bir başka nesneden yaratmak istiyoruz. A nesnesinin copy constructor metodu etkinsizleştirilmiş ancak move constructor metodu var.
Rule Of 3
Rule of 3 yazısına taşıdım.
Bu kural sadece Copy Constructor için değil kendi tipini parametre alan diğer metodlar için de geçerlidir.
Örnek
Şöyle yaparız.
class my_str {
void foo(my_str& other) {
// can access private members of both this-> and other.
}
static void bar(my_str& other) {
// can access private members of other.
}
};
ÖrnekŞöyle yaparız.
my_str::my_str(my_str&& m)
{
size_ = m.size_; //accessing private variable another my_str class
buff_ = m.buff_; //accessing private variable another my_str class
m.buff_ = nullptr;
m.size_ = 0;
}
Parametre const olabilir veya olmayabilir.
C(const C& c){...}
C(C& c){...}
Bu copy constructor değildir.C(C c){...}
Template Constructor ve Copy ConstructorElimizde şöyle bir kod olsun. Bu koddaki son satır copy constructor yerine template constructor'ı çalıştıyor. Çünkü non-const nesne'yi const yapmak maliyetli, template constructor ise direkt çağrılabiliyor.
#include <iostream>
struct uct
{
uct() { std::cerr << "default" << std::endl; }
uct(const uct &) { std::cerr << "copy" << std::endl; }
uct( uct&&) { std::cerr << "move" << std::endl; }
uct(const int &) { std::cerr << "int" << std::endl; }
uct( int &&) { std::cerr << "int" << std::endl; }
template <typename T>
uct(T &&) { std::cerr << "template" << std::endl; }
};
int main()
{
uct u1 ; // default
uct u2( 5); // int
uct u3(u1); // template, why?
}
Copy Constructor ve Assignment Operator FarkıCopy constructor ve assignment operatör aynı gibi görünse de birisi yeni nesne oluştururken çağrılır. Diğeri ise mevcut nesne için çağrılır. Aşağıdaki örneklerde yeni bir nesne yaratılıyor
f(T o) {
...}
T object;
f(object); // copy construction to pass the argument
T object2(object); // construct a T from another T
Bu örneklerlerde ise mevcut nesne güncelleniyor.T object;
...
T object2;
...
object = object2;
Assignment ile YaratmaBir nesne diğer bir nesneye eşitlenerek yaratılırsa copy constructor çağırılır. Örnek:
class Foo
{
...
};
Foo f;
Foo g = f; // (*)
Copy Constructor Ne Zaman Üretilmez
Eğer alanlardan bir veya daha fazlasının copy constructor metodu etkinsizleştirişmiş ise üretilmez. Elimizde şöyle bir sınıf olsun.
class MyClass
{
public:
MyClass(int ID) : ID(ID) { }
std::ofstream outputstream;
std::ifstream inputstream;
std::mutex mymutex;
private:
int ID;
};
Şöyle yaparsak derleyici hata verir.std::vector<MyClass> MyVector;
//<-- Error C2280 'MyClass::MyClass(const MyClass &)':
attempting to reference a deleted function
MyVector.push_back (MyClass(1));
Copy Constructor'ın Etkinsizleştirilmesi
Copy Constructor'ın Etkinsizleştirilmesi - Deleted Copy Constructor yazısına taşıdım.Copy Constructor'ın Etkinsizleştirilmesi Ancak Move Constructor Kullanılması
Copy constructor etkinsizleştirilse bile move constructor kullanmaya devam etmek isteyebiliriz.
Örnek
Bu durumda şöyle yaparız.
C(C&&) = default;
C& operator=(C&&) = default;
ÖrnekŞöyle yaparız
struct ExplicitCopy {
// Implement as usual
ExplicitCopy() = default;
ExplicitCopy(ExplicitCopy &&) = default;
ExplicitCopy &operator = (ExplicitCopy &&) = default;
// Copying happens with an ADL call to this function
friend ExplicitCopy copy(ExplicitCopy const &orig) {
return orig;
}
private:
// Copy operations are private and can't be called accidentally
ExplicitCopy(ExplicitCopy const &) = default;
ExplicitCopy &operator = (ExplicitCopy const &) = default;
};
Şöyle yaparız.ExplicitCopy ec;
ExplicitCopy ec2 = ec; // Nope
ExplicitCopy ec3(ec); // Nope
ExplicitCopy ec4 = copy(ec); // Yes
Bu duruma ne zaman ihtiyaç olur
Örnek 1 :
Bir nesne kopyalanmasın ancak temporary nesneleri de metodlardan dönebilelim istersek kullanırız. Yani şöyle yapmak istersek kullanırız.
C f() {
return C();
}
Örnek 2 :Nesnemizi geçici bir başka nesneden yaratmak istiyoruz. A nesnesinin copy constructor metodu etkinsizleştirilmiş ancak move constructor metodu var.
class A
{
public:
A(const A&) = delete;
A (const A&&) = default;
};
Şöyle yapabiliriz.
auto a = A {};
veyaA a = A {};
Rule Of 3
Rule of 3 yazısına taşıdım.
Rule of 4 And A Half
Açıklaması şöyle
“The Rule of The Big Four (and a half)" states that if you implement one ofRule of 5
* The copy constructor
* The assignment operator
* The move constructor
* The destructor
* The swap function
then you must have a policy about the others.
Rule of 5 yeni C++11 ile geldi. Rule of 3 kuralına ek olarak, move constructor ve move assignment operator'ünü de yazmaya ihtiyaç olur der.
Bence kendi bellek alanını yöneten ve raw pointer kullanan sınıfların artık hiç kullanılmaması lazım.
Clone Örneği
Ata sınıfımızda şöyle bir metod olsun.
virtual Animal* clone () const = 0;
Kalıtan sınıflar şöyle yaparlar.Rabbit* clone () const {
return new Rabbit(*this);
}
Copy constructor list initialization gibi de çağırılabilir. Şöyle yaparız.class Demo {
public:
int value1;
Demo(){}
Demo(Demo& demo) {
this->value1 = demo.value1;
}
Demo Clone() {
return Demo {*this};
}
};
Hiç yorum yok:
Yorum Gönder