- •Void Print();
- •Void print()
- •Void main()
- •Void print()
- •Void main()
- •Void main()
- •Void print()
- •Void main()
- •Void print()
- •Void main()
- •Void main()
- •Void main()
- •Void main()
- •Void main()
- •Void main()
- •Void main()
- •Void main()
- •Void print();
- •Void Drob::print()
- •Void main()
- •Void main()
- •Void print();
- •Void Drob::print()
- •Void main()
- •Void main()
- •Void main()
- •Void main()
- •Void main()
- •Void main()
- •Void main()
- •Void main()
- •Void main()
- •Void main()
- •Void main()
- •Void main()
- •Void main ()
- •Void main ()
- •Void main ()
Void main()
{
MyClass*p=new MyClass;//MyClass*p=MyClass::operator new(sizeof(MyClass));
cout<<MyClass::GetCount()<<endl;
delete p;//MyClass::operator delete (p) ;
cout<<MyClass::GetCount()<<endl;
}
СО СТРОКОЙ!
#include<iostream>
using namespace std;
class MyClass
{
static int count;
public:
void* operator new(size_t size,char *str)
{
cout<<str<<endl;
void *ptr=malloc(size);
if(ptr!=NULL)
count++;
return ptr;
}
void operator delete(void* ptr)
{
if(ptr!=NULL)
count--;
free (ptr);
}
static int GetCount()
{
return count;
}
};
int MyClass::count;
Void main()
{
MyClass*p=new("Test") MyClass;//MyClass*p=MyClass::operator new(sizeof(MyClass),"Test");
cout<<MyClass::GetCount()<<endl;
delete p;//MyClass::operator delete (p) ;
cout<<MyClass::GetCount()<<endl;
}
ПЕРЕГРУЗКА ->
Тип * operator ->()
Оператор -> перегружается как унарная операция и он должен быть определен как метод класса .
Перегрузка операции -> используется для создания умных указателей .
Умный указатель – это класс , имитирующий интерфейс обычного указателя и добавляющий новую функциональность , например , очистку памяти .
Проблемы , связанные с использованием обычных указателей .
1)Указатель не управляет временем жизни объекта. Ответственность за удаление объекта переходит на программиста. В этой ситуацией говорят , что указатель не владеет объектом.
2)Нет возможности проверить указывает ли указатель на корректные данные , либо в никуда.
3)Указатели , ссылающиеся на один и тот же объект – никак не связаны между собой. Это создает проблему битых указателей, то есть указателей ссылающихся на освобожденные объекты.
4)Указатель на единичный объект или указатель на массив , никак не отличаются друг от друга.
Решение проблемы
1)Указатель не владеет объектом .
РЕШЕНИЕ:
Вместо обычного указателя использовать объект , хранящий указатель и освобождающий его в своем деструкторе .
#include <iostream>
using namespace std;
class MyClass
{
public:
void method()
{
cout<<"MyClass::method \n";
}
};
class Smart_ptr
{
private:
MyClass* p;
public:
Smart_ptr(MyClass *ptr=NULL)
{
p=ptr;
}
~Smart_ptr()
{
delete p;
}
MyClass& operator*()
{
return *p;
}
MyClass* operator->()
{
return p;
}
};
Void main()
{
Smart_ptr sPtr=new MyClass;
sPtr->method();
}
2)Разыменование значения NULL
РЕШЕНИЕ:
Необходимо при разыменовании селектора необходимо делать проверку на значении 0 .
#include <iostream>
using namespace std;
class MyClass
{
public:
void method()
{
cout<<"MyClass::method \n";
}
};
class Smart_ptr
{
private:
MyClass* p;
public:
Smart_ptr(MyClass *ptr=NULL)
{
p=ptr;
}
~Smart_ptr()
{
delete p;
}
MyClass& operator*()
{
if(p==NULL)
{
cout<<"pointer is NULL \n";
p=new MyClass;
}
return *p;
}
MyClass* operator->()
{
if(p==NULL)
{
cout<<"pointer is NULL \n";
p=new MyClass;
}
return p;
}
};