Форум программистов, компьютерный форум CyberForum.ru

Указатель на бызовый абстрактный класс. - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 23, средняя оценка - 4.91
zhenya.ya
1 / 1 / 0
Регистрация: 29.11.2009
Сообщений: 304
10.11.2010, 21:18     Указатель на бызовый абстрактный класс. #1
Правильно ли у меня написан "умный" указатель? Напонятно, как можно с помощью указателя на базовый класс вызывать методы производных классов ( все указатели должны быть "умными").
Т.е. если бы они были простыми, а не "умными" сделал бы так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
base *p;
       first fst;
       second snd;
 
       p=&fst;
       p->AddDate();
       p->WeightSort();
       p->print();
  
       p = &snd;
       p->AddDate();
       p->print();
//1.cpp Smart pointer (Умный указатель)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class A
{
private:
    int count;
public:
    A(){ count =0;}
    void add(){ count ++;}
    void del(){ if(--count==NULL) delete this;}
};
class Aptr
{
private:
    A *aptr;
public:
    Aptr(A *p) { aptr=p; p->add();}
    ~Aptr(){ aptr->del();}
    A * operator ->() {return aptr;}
};
// 2.cpp базовый абстрактный и 2 производных класса
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class base
{
public:
    int n;
    base(){n=0;}
    virtual ~base(){}
    virtual void AddDate()=0;
    virtual void print()=0;
    virtual void WeightSort(){}
};
class first:public base
{
public:
    first(){naznachenie=NULL; weight=NULL;}
    virtual ~first();
    void AddDate();
    void print(){}
    void WeightSort(); 
private:
    char **naznachenie;
    int *weight;
};
class second:public base
{
public:
    second(){adress=NULL;}
    virtual ~second();
     void AddDate();
    void print(){}
private:
    char **name;
    char **adress;
};
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.11.2010, 21:18     Указатель на бызовый абстрактный класс.
Посмотрите здесь:

Создать абстрактный тип данных (структура) - вектор, который имеет указатель на short и число элементов C++
Написать обработчик исключений ситуации при преобразовании указателя на класс B до указателя на абстрактный класс А ... C++
Создать абстрактный тип данных - класс вектор, который имеет указатель на long, число элементов и переменную состояния C++
C++ Абстрактный класс
Создание объекта через указатель на базовый абстрактный класс C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
volovzi
266 / 168 / 8
Регистрация: 14.03.2010
Сообщений: 501
10.11.2010, 23:03     Указатель на бызовый абстрактный класс. #2
Вся работа с умными указателями, кроме их объявления, должна происходить точно так же, как и с обычными.

Для начала попробуй std::auto_ptr. Возможно, он удовлетворяет твоим потребностям.

Если же нет, то можешь попробовать вот это:
xtl_memory.h

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#ifndef _XTL_MEMORY_H
#define _XTL_MEMORY_H
 
#include <memory>
#include <map>
 
namespace xtd {
 
//!     Умный указатель.
/*! 
        Умеет работать только с одной иерархией, т.е. только с классом "type" и его наследниками. К другим типам не преобразуется.
*/
template <typename type>
class shared_ptr {
private:
    // ---- Определения ---------------------------------------------------------------------------
    
    class traits {
    public:
        traits (type * some_pointer) : pointer(some_pointer), reference_count(1) {}
        ~traits () { delete pointer; }
        
        void retain () { ++reference_count; }
        bool release () { return --reference_count == 0; }
        
        type * get () const { return pointer; }
        
    private:    
        type * const pointer;
        int reference_count;
    };
    
public:
    // ---- Создание и уничтожение ----------------------------------------------------------------
    
    shared_ptr () : m_traits(0) {}
    shared_ptr (type * some_pointer) : m_traits(new traits(some_pointer)) {}
    shared_ptr (const shared_ptr & some_shared_pointer) : m_traits(0) { copy(some_shared_pointer); }
    ~shared_ptr () { release(); }
    
    // ---- Модификация ---------------------------------------------------------------------------
    
    shared_ptr & operator = (const shared_ptr & some_shared_pointer) {
        copy(some_shared_pointer);
        
        return *this;
    }
    
    // ---- Операции сравнения --------------------------------------------------------------------
    
    bool operator == (const shared_ptr & some_shared_pointer) const { return m_traits == some_shared_pointer.m_traits; }
    bool operator != (const shared_ptr & some_shared_pointer) const { return m_traits != some_shared_pointer.m_traits; }
    
    // ---- Доступ --------------------------------------------------------------------------------
    
    type & operator * () const { return *m_traits->get(); }
    type * operator -> () const { return m_traits->get(); }
 
protected:
    // ---- Служебные функции ---------------------------------------------------------------------
    
    void retain () const { if (m_traits) m_traits->retain(); }
    void release () const { if (m_traits && m_traits->release()) delete m_traits; }
    
    void copy (const shared_ptr & some_shared_pointer) {
        release();
        m_traits = some_shared_pointer.m_traits;
        retain();
    }
    
private:
    traits * m_traits;
};
 
}
 
#endif

либо boost::shared_ptr.
zhenya.ya
1 / 1 / 0
Регистрация: 29.11.2009
Сообщений: 304
10.11.2010, 23:40  [ТС]     Указатель на бызовый абстрактный класс. #3
Мне по условию сказали использовать "умный" указатель, который считает и удаляет ссылки ( т.е. Ваш 2 пример). А про "Авто птр" сказили, что его вообще не стоит никогда использовать.

Я вот постарался сделать как по вашему примеру, но не понял как завернуть в шаблон.Правильно ли я сделал и как заворачиваются такие конструкции в шаблон ?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Aptr
{
private:
    class A {
private:
    int count;
public:
    A(){ count =0;}
    void add(){ count ++;}
    void del(){ if(--count==NULL) delete this;}
};
private:
    A *aptr;
public:
    Aptr(A *p) { aptr=p; p->add();}
    ~Aptr(){ aptr->del();}
    A * operator ->() {return aptr;}
};
void main(){}
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
10.11.2010, 23:44     Указатель на бызовый абстрактный класс. #4
zhenya.ya, auto_ptr имеет ограниченную область использования. И в некоторых случаях очень даже полезен.
volovzi
266 / 168 / 8
Регистрация: 14.03.2010
Сообщений: 501
11.11.2010, 00:07     Указатель на бызовый абстрактный класс. #5
zhenya.ya, класс, на экземпляр которого указывает умный указатель, не должен заниматься подсчётом ссылок на самого себя. Для этого и существует сам умный указатель. Попробуй повнимательнее разобрать мой пример. Если что, непонятные места разъясню.

А насчёт std::auto_ptr тебе наврали. Это очень полезная штука. Хотя и не без особенностей.
zhenya.ya
1 / 1 / 0
Регистрация: 29.11.2009
Сообщений: 304
11.11.2010, 00:11  [ТС]     Указатель на бызовый абстрактный класс. #6
auto_ptr имеет ограниченную область использования. И в некоторых случаях очень даже полезен.
С удовольствием бы стал подходить к реализации задания через auto_ptr, но по условию, к сожалению, нужно использовать то , что я попытался реализовать. Правильно ли я это сделал и ,если да, то как это в шаблон завернуть?
volovzi
266 / 168 / 8
Регистрация: 14.03.2010
Сообщений: 501
11.11.2010, 00:14     Указатель на бызовый абстрактный класс. #7
Нет, неправильно. Подсчёт ссылок должен происходить в указателе, а не в хранящемся классе. См. пример.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
11.11.2010, 00:24     Указатель на бызовый абстрактный класс. #8
volovzi, Интересный пример. Сами написали?
zhenya.ya
1 / 1 / 0
Регистрация: 29.11.2009
Сообщений: 304
11.11.2010, 00:33  [ТС]     Указатель на бызовый абстрактный класс. #9
Вопросов много:
1) для чего это нужно?
C++
1
2
3
4
5
6
7
class traits
{
public:
...
type * get () const { return pointer; }
private:        
                type * const pointer;
2) что тут происходит:
C++
1
shared_ptr (type * some_pointer) : m_traits(new traits(some_pointer)) {}
volovzi
266 / 168 / 8
Регистрация: 14.03.2010
Сообщений: 501
11.11.2010, 00:38     Указатель на бызовый абстрактный класс. #10
ForEveR, подсматривал чужие исходники, конечно, но, в целом, да.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
11.11.2010, 00:47     Указатель на бызовый абстрактный класс. #11
zhenya.ya,
Разделение.
Собственно тут как я понимаю подсчитываются ссылки.
C++
1
2
3
4
5
6
7
8
9
10
11
class traits
{
public:
...
//Возврат указателя шаблонного типа type.
//pointer - член класса traits
type * get () const { return pointer; }
private:
//Я впринципе путаюсь иногда, но по-моему
//константный указатель на тип Type     
                type * const pointer;
volovzi
266 / 168 / 8
Регистрация: 14.03.2010
Сообщений: 501
11.11.2010, 00:51     Указатель на бызовый абстрактный класс. #12
zhenya.ya
1) идея в том, что изменение счётчика ссылок не должно модифицировать сам умный указатель. Для этого счётчик хранится в динамической памяти, а обращение к нему происходит по указателю. А изменение значения указателя не является модификацией класса.
Если же ты имеешь в виду зачем нужна функция "get", то, в принципе, можно объявить переменную "pointer" публичной и убрать эту функцию.
2) тут происходит инициализация переменной "m_traits" указателем на вновь созданный объект с вызовом его (единственного) конструктора.
zhenya.ya
1 / 1 / 0
Регистрация: 29.11.2009
Сообщений: 304
11.11.2010, 01:18  [ТС]     Указатель на бызовый абстрактный класс. #13
Не могли бы Вы сказать, каким образом работают:
protected:

void retain () const { if (m_traits) m_traits->retain(); }
void release () const { if (m_traits && m_traits->release()) delete m_traits; }
И что что означает "const" ?
volovzi
266 / 168 / 8
Регистрация: 14.03.2010
Сообщений: 501
11.11.2010, 01:33     Указатель на бызовый абстрактный класс. #14
Если написать
C++
1
if (m_traits != 0) ...
то станет понятнее?
Если под указатель "m_traits" выделена память, то с ним происходит соответствующая работа. В первом случае вызывается функция увеличения счётчика ссылок, а во втором — вызов уменьшения счётчика. Причём функция уменьшения счётчика возвращает индикатор того, стал ли равен счётчик нулю, и если стал, то происходит удаление переменной "m_traits".

Слово "const" означает, что данная функция не изменяет состояние экземпляра данного класса.
zhenya.ya
1 / 1 / 0
Регистрация: 29.11.2009
Сообщений: 304
11.11.2010, 01:46  [ТС]     Указатель на бызовый абстрактный класс. #15
Вроде почти все учел. Как же теперь правильно этим воспользоваться в main() ?
C++
1
2
3
4
void main()
{
    Aptr <first> fst;
               ... ?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
template <typename type>
class Aptr
{
private:
 
    class A {
 
private:
    int count;
    type *pointer;
 
public:
 
    A(type *some_pointer) {pointer = some_pointer,count =1;}
    ~A(){delete []pointer;}
    void add(){ count ++;}
    void del(){ if(--count==NULL) delete this;}
    type * get ()  { return pointer; }
    };
 
public:
    Aptr() { aptr = 0;}
    Aptr(type *some_pointer) { aptr = new A(some_pointer);}
    ~Aptr() {del();}
 
protected:
     void add() { aptr->add();}
     void del(){ aptr->del();}
    type * operator ->() {return aptr->get();}
 
private:
    A *aptr;
};
volovzi
266 / 168 / 8
Регистрация: 14.03.2010
Сообщений: 501
11.11.2010, 02:24     Указатель на бызовый абстрактный класс. #16
C++
1
2
        ~A() {delete [] pointer;} // Почему ты удаляешь массив? Здесь нужен "delete", а не "delete []".
        void del(){ if(--count==NULL) delete this;} // Почему ты сравниваешь int с NULL? NULL — это нулевой указатель. Здесь нужен просто 0.
И ещё нужно определить оператор "звёздочка":
C++
1
    type & operator * () const { return *m_traits->get(); }
чтобы можно было обращаться к содержимому массива.

Ещё нельзя делать
C++
1
delete this
Нужно удалять A из Aptr. Aptr память выделяет, Aptr и должен её уничтожать.

И ещё:
Конструктор без параметров должен устанавливать указатель на "aptr" в ноль, а функции "Aptr::add" и "Aptr::del" всё-таки перед вызовом должны проверять указатель на ноль, иначе может возникнуть ситуация, когда ты вызываешь метод объекта, которого не существует.

А пользоваться в мейне как обычным указателем.
zhenya.ya
1 / 1 / 0
Регистрация: 29.11.2009
Сообщений: 304
11.11.2010, 02:29  [ТС]     Указатель на бызовый абстрактный класс. #17
А обращаться к указателю надо как к обычному.
т.е. даже так можно?
C++
1
2
3
4
5
base *aptr;
first fst;
aptr=&fst;
aptr->AddDate();
aptr->print();
volovzi
266 / 168 / 8
Регистрация: 14.03.2010
Сообщений: 501
11.11.2010, 02:35     Указатель на бызовый абстрактный класс. #18
Нет,
C++
1
2
Aptr<base> ptr;
...
А дальше как и раньше.

Добавлено через 2 минуты
Ой, нет, не совсем.
Тебе нужно перегрузить оператор присвоения как у меня, и тогда ты сможешь делать так:
C++
1
2
3
4
5
6
7
8
9
10
Aptr<base> ptr;
ptr = new first;
ptr->AddDate();
...
 
ptr = new second;
ptr->AddDate();
...
 
и удалять указатель не надо.
zhenya.ya
1 / 1 / 0
Регистрация: 29.11.2009
Сообщений: 304
11.11.2010, 03:29  [ТС]     Указатель на бызовый абстрактный класс. #19
А для чего в операторе =
C++
1
copy(some_shared_pointer);
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.11.2010, 07:52     Указатель на бызовый абстрактный класс.
Еще ссылки по теме:

Создать абстрактный тип данных (структура) — вектор, который имеет указатель на int и число элементов C++
Что такое указатель на абстрактный класс? C++
Абстрактный класс/Класс интерфейс C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
11.11.2010, 07:52     Указатель на бызовый абстрактный класс. #20
zhenya.ya, Вызов функции копирования объекта в this
Yandex
Объявления
11.11.2010, 07:52     Указатель на бызовый абстрактный класс.
Ответ Создать тему
Опции темы

Текущее время: 20:20. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru