Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Конструктор потомка, неявный вызов 
V
    Опции темы
Snowy
Дата 23.1.2006, 14:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



Вот такая головоломка меня преследует:
Код

  TCustomClass = class // предок
  private
    MyName: string; // переменная, задается в конструкторе
  public
    constructor Create; // соответственно конструктор
    function SayYourName:string; virtual; // метод, есть в родителе и потомке
  end;

  TMyClass = class(TCustomClass) // потомок. В примере только один
    constructor Create; // конструктор потомка! Вот он мне и нужен!
    function SayYourName: string; override; // метод
  end;

  TClasses = class of TCustomClass; // определяет тип класса, создаваемого объекта

var Form1: TForm1;

implementation
{$R *.dfm}

function CreateNewClass(ClassId: TClasses):TCustomClass; // Функция, которая создает новый объект
begin  // неизвестного пока нам класса. Конкретный класс будет определен позже
  result := ClassId.Create; // вот, мы вызываем конструктор
end;

constructor TCustomClass.Create; // конструктор родителя
begin
  inherited;
  MyName := 'Кустомчик';
end;

constructor TMyClass.Create; // конструктор потомка. Не вызывается никогда!!! А надо!
begin
  inherited;
  MyName := 'Потомок Кустомчика';
end;

function TCustomClass.SayYourName; // реализация функции родителя
begin
  result := MyName;
end;

function TMyClass.SayYourName; // реализация функции потомка
begin
  result := 'Меня зовут ' + MyName;
end;

procedure TForm1.Button1Click(Sender: TObject); // действие
begin
  with CreateNewClass(TMyClass) do // вот мы вызываем конструктор. Говорит, создай нам потомка.
  begin
    ShowMessage(SayYourName + #13#10 + ClassName); // Проверяем, что же у нас получилось...
    Free;
  end;
end;

Итого, в результате примера данного кода получаем следующее.
Смотрим последнюю часть - действие.
1. Вызывается функция, которая создает нам объект. Сообщаем ей, что хотим потомка.
2. Функция вызывает конструктор. Но! Вызывается конструктор не потомка, а предка!!!!! smile
Конструктор потомка вообще не вызывается!!!
Трейсил все по F7. В конструктор потомка не идет!
3. Отработал конструктор предка. Проверяем, что же мы создали.
Как видим, функция в потомке отличается от функции в предке.
Вызываем ее. Вызывается функция потомка. ClassName - тоже = 'TMyClass'.
То есть, у нас определенно создался потомок, несмотря на то, что его конструктор не отработал.
Но! Т.к. конструктор не отработал, то в MyName находится данные родителя.
Это всего лишь пример. А в реале мне нужно в потомке создавать объекты в конструкторе.
Объекты не создаются, а в функционале потомка идет к ним обращения.
Вот и мучаюсь.
Выход вроде простой - создать функции Init и Done.
Но с объектной точки зрения это бред, т.к. для этого и преднозначен конструктор.
Да и вообще интересно, почему именно так? Почему создается потомок, все функции потомка, а конструктор предка?
Добавлено @ 15:07
Замечено, что если:
Код
function CreateNewClass(ClassId: TClasses):TCustomClass;
begin
  result := ClassId.Create;
end;
заменить на
Код
function CreateNewClass(ClassId: TClasses):TCustomClass;
begin
  result := TMyClass.Create;
end;
, то все отрабатывает правильно.
Но мне пока не известно, какого именно потомка я буду создавать.
Для этого и передаю класс потомка, как параметр.
Все отлично, все отрабатывает корректно, кроме конструктора. Why?
PM MAIL   Вверх
Bose
Дата 23.1.2006, 15:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1458
Регистрация: 5.3.2005
Где: Riga, Latvia

Репутация: 23
Всего: 51



а может так?

Код

  TMyClass = class(TCustomClass) // потомок. В примере только один    
    constructor Create; override;// override или overload...
    function SayYourName: string; override; // метод    
  end;

PM MAIL WWW Skype   Вверх
Snowy
Дата 23.1.2006, 15:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



Нет, override только для виртуальных методов. А конструктор статичный.
Добавлено @ 15:19
Во как.
Сделал конструктор виртуальным, а у потомка сделал override.
Заработало!!!
Хм. Нужно будет подумать...
Спасибо, с меня жирный +
PM MAIL   Вверх
Bose
Дата 23.1.2006, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1458
Регистрация: 5.3.2005
Где: Riga, Latvia

Репутация: 23
Всего: 51



сам когда-то столкнулся с подобным smile

как вариант еще можно попробовать обьявить конструктор с overload. кажется должно сработать. насколько такое обьявление корректно - того не знаю не ведаю smile
PM MAIL WWW Skype   Вверх
Snowy
Дата 23.1.2006, 15:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



Нет, оверлоад тут совсем не к месту. Он нужен при наличии нескольких конструкторов. А у меня один.
А вот виртуальный конструктор - самое то.

PM MAIL   Вверх
Bose
Дата 23.1.2006, 16:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1458
Регистрация: 5.3.2005
Где: Riga, Latvia

Репутация: 23
Всего: 51



ну да.... у меня в общем-то и было несколько конструкторов. Но дело в том, что оверлоад также позволяет вызвать конструктор потомка для статично обьявленного конструктора предка. (если я ничего не путаю).
PM MAIL WWW Skype   Вверх
Snowy
Дата 23.1.2006, 16:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



Цитата(Bose @ 23.1.2006, 16:00 Найти цитируемый пост)
Но дело в том, что оверлоад также позволяет вызвать конструктор потомка для статично обьявленного конструктора предка.

Неа. Не вызывает. Пробовал.
PM MAIL   Вверх
Bose
Дата 23.1.2006, 16:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1458
Регистрация: 5.3.2005
Где: Riga, Latvia

Репутация: 23
Всего: 51



значит путаю smile
PM MAIL WWW Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0500 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.