C++Builder
  Начало   Форум   Помощь Войти Регистрация  
Страниц: [1]   Вниз
  Печать  
Автор Тема: Расширить экземпляр базового класса к наследованному классу  (Прочитано 2650 раз)
1daan1
Участник


Сказали спасибо: +0/-0
Offline

Сообщений: 11


Расширить экземпляр базового класса к наследованному классу
« : 14 Февраль 2012, 15:12:05 »

Имеются два класса:
Код
class base
{
 public:
   int counter;
};
 
class inherit:public base
{
 public:
   AnsiString row;
};
 
Есть функция, которая должна работать с класcом base, и не должна знать о существовании класса inherit. При этом она может выделять память экземпляру класса.
Код
void doSomeWithBase(base *a)
{
 a=new base;
 a->counter=0;
}
 
Программа работает с экземплярами типа inherit, к примеру, так:
Код
void doSomeWithInherit(inherit *a)
{
 if (a->counter)
   ShowMessage(a->row);
}
 
Нужно реализовать следующую возможность:
Код
  base *simple;
 inherit *complex;
 doSomeWithBase(simple);
//expand simple to complex, for example:
 complex=(inherit*)simple;  //wrong!
 doSomeWithInherit(complex);
 
Понятно что память выделяется только по размеру base, и при попытке использовать методы/изменить свойства inherit получается Access Violation.
Выделять память вне функции  doSomeWithBase нежелательно, так как программа не знает, сколько экземпляров создаст функция.
Есть решение
Код
  base *simple;
 inherit *complex;
 doSomeWithBase(simple);
 
 complex=new inherit;
 complex=simple;
 
 doSomeWithInherit(complex);
 
которое опять же нежелательно, поскольку размер base может быть довольно большим.

Возможно ли расширить базовый клас к наследованному, не применяя копирование?
Записан
gumi250
Участник


Сказали спасибо: +33/-1
Offline

Сообщений: 254


Re: Расширить экземпляр базового класса к наследованному классу
« Ответ #1 : 14 Февраль 2012, 15:29:53 »

Я правильно понял что вы хотите создавать с помощью new экземпляр класса base (скажем 100 байт), и потом чудным образом добавлять ему памяти (до 150 байт) причем не копированием в новую область памяти, а именно дописыванием дополнительной памяти к экземпляру класса base?
Код:
  complex=new inherit;
  complex=simple;
Что это за источник утечек памяти?
Записан
1daan1
Участник


Сказали спасибо: +0/-0
Offline

Сообщений: 11


Re: Расширить экземпляр базового класса к наследованному классу
« Ответ #2 : 14 Февраль 2012, 15:48:19 »

Правильно. Только размеры немножко не те. base, к примеру, может содержать 10 миллионов точек (два массива double размером 107 каждый), а inherit - десяток строковых переменных, пару double, несколько bool, т.е. размер до килобайта. Причем массивы base задекларированы как private, и копирование осуществляется с помощью copy-конструктора.
Утечек памяти нет быть не должно, поскольку дальше, как правило, следует delete simple;
Записан
gumi250
Участник


Сказали спасибо: +33/-1
Offline

Сообщений: 254


Re: Расширить экземпляр базового класса к наследованному классу
« Ответ #3 : 14 Февраль 2012, 15:57:45 »

А может быть в классе base хранятся не сами массивы, а лишь указатели на них? И сам класс base весит куда меньше? 10мегабайт это не много и в памяти копируются примерно за 1мс., может вам не столь часто нужно создавать inherit?
Цитата: 1daan1 от 14 Февраль 2012, 15:48:19
Цитировать
Код:
  complex=new inherit;
  complex=simple;
Что это за источник утечек памяти?
Утечек памяти нет быть не должно, поскольку дальше, как правило, следует delete simple;
а кто удалит созданный inherit?
Записан
1daan1
Участник


Сказали спасибо: +0/-0
Offline

Сообщений: 11


Re: Расширить экземпляр базового класса к на&
« Ответ #4 : 14 Февраль 2012, 16:27:11 »

Массивы динамические. В base естественно хранятся указатели. Только задекларированы они как private, и доступ к ним должны иметь только методы base.
10 миллионов точек - это 2*(10 МБайт)*sizeof(double), т.е. 160 МБайт.
Иногда нужно создавать именно копию экземпляра base, поэтому base имеет copy-конструктор, который дублирует массивы источника, т.е. в результате
Код
complex=simple;
и simple, и complex занимают по 160 МБайт.
В процессе работы программы могут существовать теоретически неограниченное количество экземпляров base/inherit (практически - сколько позволит память), которые должны обрабатываться одновременно. Малейшая задержка при копировании base может вылится в ощутимый подвисон.

Созданный inherit удалит основная программа при необходимости.
« Последнее редактирование: 14 Февраль 2012, 17:27:31 от 1daan1 » Записан
volvo877
Глобальный модератор


Сказали спасибо: +736/-1
Offline

Сообщений: 891


Re: Расширить экземпляр базового класса к наследованному классу
« Ответ #5 : 14 Февраль 2012, 16:40:19 »

1daan1, объясни мне одну простую вещь: зачем тебе тут наследование?

Если ты в inherit добавишь указатель на base, и будешь передавать simple в его конструктор, то ты добьешься нужного поведения безо всякого копирования. Итак, вопрос остается в силе: чего ты добиваешься наследованием? Нужен общий предок?
Записан
1daan1
Участник


Сказали спасибо: +0/-0
Offline

Сообщений: 11


Re: Расширить экземпляр базового класса к на&
« Ответ #6 : 14 Февраль 2012, 17:44:24 »

Есть куча функций типа
Код
void DoSomethingWith(base *target)
{
//........
}
 
которые должны обрабатывать как base, так и inherit. В принципе, можно переделать на указатель, но это потребует кучу правок по ходу основного кода. Тогда уж лучше реализовать обмен указателями на массивы данных между классами.

Но все  это отход от темы. Меня интересует именно возможность довыделения памяти для класса.
Записан
gumi250
Участник


Сказали спасибо: +33/-1
Offline

Сообщений: 254


« Ответ #7 : 15 Февраль 2012, 00:36:20 »

Превратить экземпляр базового класса в больший по размеру экземпляр наследного класса путем добавления памяти невозможно. Память за экземпляром базового класса может быть занята, там могут находится другие переменные, что прикажете с ними делать? Память всегда не добавляется а выделяется заново.
Цитировать
Есть куча функций типа
Код:
void DoSomethingWith(base *target)
{
//........
}
которые должны обрабатывать как base, так и inherit.
Эти ф-ции и так будут корректно обрабатывать и  base и inherit (вы ведь в них не будете использовать св-ва  inherit )
Ваша задумка противоречит идеологии с++, нужно переделывать идеологию программы, а не ставить костыли.

P.S. т.к. основные массивы динамические, то сам класс занимает гораздо меньше места. В принципе можно не пользоваться конструктором копий, а выделить новый участок памяти размером в класс наследник и скопировать в него участок памяти базового класса, затем память базового класса освободить. Еще надо поправить все указатели целящиеся на старый экземпляр базового класса. При этом массивы копироваться не будут. Но это идеологически неправильно и небезопасно.
« Последнее редактирование: 15 Февраль 2012, 01:08:56 от gumi250 » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  




....

Powered by SMF 1.1.21 | SMF © 2025, Simple Machines
Страница сгенерирована за 0.124 секунд. Запросов: 19.