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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 23, средняя оценка - 4.91
zhenya.ya
1 / 1 / 0
Регистрация: 29.11.2009
Сообщений: 305
#1

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

10.11.2010, 21:18. Просмотров 3087. Ответов 30
Метки нет (Все метки)

Правильно ли у меня написан "умный" указатель? Напонятно, как можно с помощью указателя на базовый класс вызывать методы производных классов ( все указатели должны быть "умными").
Т.е. если бы они были простыми, а не "умными" сделал бы так:
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;
};
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.11.2010, 21:18
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Указатель на бызовый абстрактный класс. (C++):

Что такое указатель на абстрактный класс? - C++
В задании сказано - Методы класса должны принимать указатель на абстрактный класс , что это значит и как это реализовывается?

Скопировать объект, на который ссылается указатель на абстрактный класс - C++
Доброго времени суток. У меня такое задание: написать программу символьного дифференцирования, т.е. пользователь пишет функцию f(x), а...

Создание объекта через указатель на базовый абстрактный класс - C++
Есть абстрактный класс, от него наследуется 3 класса. В программе предусмотрено создание нового объекта(добавление клиента страховой...

Создать абстрактный тип данных - класс вектор, который имеет указатель на long, число элементов и переменную состояния - C++
Помогите пожалуйста, нужно написать код на с++ Создать абстрактный тип данных - класс вектор, который имеет указатель на long, число...

Класс: Создать абстрактный базовый класс Figure с виртуальными методами вычисления площади и периметра. - C++
Создать абстрактный базовый класс Figure с виртуальными методами вычисления площади и периметра. Создать производные классы: Rectangle...

Абстрактный класс, наследование, класс хранится в другом классе - C++
Нужна помощь. Написать программу: 1 класс. Имеется абстрактный класс который описывает какую-то сущность, например Человек. В абстрактном...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
volovzi
267 / 169 / 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.
2
zhenya.ya
1 / 1 / 0
Регистрация: 29.11.2009
Сообщений: 305
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(){}
0
ForEveR
В астрале
Эксперт С++
7972 / 4734 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
10.11.2010, 23:44 #4
zhenya.ya, auto_ptr имеет ограниченную область использования. И в некоторых случаях очень даже полезен.
0
volovzi
267 / 169 / 8
Регистрация: 14.03.2010
Сообщений: 501
11.11.2010, 00:07 #5
zhenya.ya, класс, на экземпляр которого указывает умный указатель, не должен заниматься подсчётом ссылок на самого себя. Для этого и существует сам умный указатель. Попробуй повнимательнее разобрать мой пример. Если что, непонятные места разъясню.

А насчёт std::auto_ptr тебе наврали. Это очень полезная штука. Хотя и не без особенностей.
0
zhenya.ya
1 / 1 / 0
Регистрация: 29.11.2009
Сообщений: 305
11.11.2010, 00:11  [ТС] #6
auto_ptr имеет ограниченную область использования. И в некоторых случаях очень даже полезен.
С удовольствием бы стал подходить к реализации задания через auto_ptr, но по условию, к сожалению, нужно использовать то , что я попытался реализовать. Правильно ли я это сделал и ,если да, то как это в шаблон завернуть?
0
volovzi
267 / 169 / 8
Регистрация: 14.03.2010
Сообщений: 501
11.11.2010, 00:14 #7
Нет, неправильно. Подсчёт ссылок должен происходить в указателе, а не в хранящемся классе. См. пример.
0
ForEveR
В астрале
Эксперт С++
7972 / 4734 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
11.11.2010, 00:24 #8
volovzi, Интересный пример. Сами написали?
0
zhenya.ya
1 / 1 / 0
Регистрация: 29.11.2009
Сообщений: 305
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)) {}
0
volovzi
267 / 169 / 8
Регистрация: 14.03.2010
Сообщений: 501
11.11.2010, 00:38 #10
ForEveR, подсматривал чужие исходники, конечно, но, в целом, да.
0
ForEveR
В астрале
Эксперт С++
7972 / 4734 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 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;
0
volovzi
267 / 169 / 8
Регистрация: 14.03.2010
Сообщений: 501
11.11.2010, 00:51 #12
zhenya.ya
1) идея в том, что изменение счётчика ссылок не должно модифицировать сам умный указатель. Для этого счётчик хранится в динамической памяти, а обращение к нему происходит по указателю. А изменение значения указателя не является модификацией класса.
Если же ты имеешь в виду зачем нужна функция "get", то, в принципе, можно объявить переменную "pointer" публичной и убрать эту функцию.
2) тут происходит инициализация переменной "m_traits" указателем на вновь созданный объект с вызовом его (единственного) конструктора.
0
zhenya.ya
1 / 1 / 0
Регистрация: 29.11.2009
Сообщений: 305
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" ?
0
volovzi
267 / 169 / 8
Регистрация: 14.03.2010
Сообщений: 501
11.11.2010, 01:33 #14
Если написать
C++
1
if (m_traits != 0) ...
то станет понятнее?
Если под указатель "m_traits" выделена память, то с ним происходит соответствующая работа. В первом случае вызывается функция увеличения счётчика ссылок, а во втором — вызов уменьшения счётчика. Причём функция уменьшения счётчика возвращает индикатор того, стал ли равен счётчик нулю, и если стал, то происходит удаление переменной "m_traits".

Слово "const" означает, что данная функция не изменяет состояние экземпляра данного класса.
0
zhenya.ya
1 / 1 / 0
Регистрация: 29.11.2009
Сообщений: 305
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;
};
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.11.2010, 01:46
Привет! Вот еще темы с ответами:

Указатель на абстрактный шаблонный класс - C++
Есть абстрактный шаблон класса и 3 производных от него шаблонов классов. Так же есть шаблонная функция, в которую нужно передать указатель...

Создать абстрактный базовый класс Тройка чисел с виртуальными методами увеличения на 1. Создать производный класс Время со своими функциями - C++
Здравствуйте, пожалуйста помогите написать код к данной задаче, с таким условием: Создать абстрактный базовый класс Тройка чисел с...

Написать обработчик исключений ситуации при преобразовании указателя на класс B до указателя на абстрактный класс А ... - C++
Написать обработчик исключений ситуации при преобразовании указателя на класс B до указателя на абстрактный класс А ... как сделать...

Абстрактный класс/Класс интерфейс - C++
Не ловлю суть в чем разница между интерфейсом и абстрактным классом. И там и там у методов нету реализации. Ну интерфейс задает набор...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
11.11.2010, 01:46
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru