Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: 1 [2]  Все   Вниз
  Печать  
Автор Тема: Виртуальные конструкторы  (Прочитано 47161 раз)
0 Пользователей и 9 Гостей смотрят эту тему.
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #30 : 10-09-2008 06:24 » 

мда, очень прикольно получается. Говорим о том что, существование виртуального конструктора это бессмыслица, но и говорить о том что его не существует, тоже бессмыслица Улыбаюсь
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
zubr
Гость
« Ответ #31 : 10-09-2008 07:00 » 

sss, дело в том, что в Delphi (в отличие от C++) в конструкторе класса-наследника конструктор родительского класса автоматически не вызывается, его можно вызывать (а можно не вызывать, правда последствия могут быть разными) с помощью ключевого слова inherited. То есть конструктор родительского класса вызывается как обычный метод, отсюда - почему бы ему не быть виртуальным?
Записан
sss
Специалист

ru
Offline Offline

« Ответ #32 : 10-09-2008 07:44 » 

Цитата
Ты понимаешь, что такое метакласс? Для чего появились метаклассы сперва в Smalltalk, а потом расползлись по другим языкам?

Дак объясни наконец что такое матакласс. Никогда не пользовался. Два раза спрашивал - что значит virtual constructor?

zubr, ни фига подобного... Или фига подобного? Может именно когда virtual constructor такое поведение?
« Последнее редактирование: 10-09-2008 07:47 от sss » Записан

while (8==8)
zubr
Гость
« Ответ #33 : 10-09-2008 08:51 » 

Цитата
zubr, ни фига подобного... Или фига подобного? Может именно когда virtual constructor такое поведение?
Код:
TA = class
  private
  public
    constructor Create;
  end;

  TB = class(TA)
  public
    constructor Create;
  end;


constructor TA.Create;
begin
 MessageBox(0, 'A', '', MB_OK);
end;

constructor TB.Create;
begin
 inherited Create;
 MessageBox(0, 'B', '', MB_OK);
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  b:TB;
begin
 b:=TB.Create;
end;
При нажатии на Button1 выскакивает сначала A затем B. Если конструктор TB  сделать без inherited то только В. Все тоже самое если объявить:
Код:
TA = class
  private
  public
    constructor Create; virtual;
  end;

  TB = class(TA)
  public
    constructor Create; override;
  end;
Записан
sss
Специалист

ru
Offline Offline

« Ответ #34 : 10-09-2008 09:07 » 

А как инициализированы члены класса? Зарезервированным словом default? А конструкторы классов членов вызываются?

Все сдаюсь... Надоело говорить про Delphi в теме об ANSI C++. Только не знаю, что признать то? Суверенитет ObjectPascal???
Записан

while (8==8)
zubr
Гость
« Ответ #35 : 10-09-2008 09:34 » 

Цитата
А как инициализированы члены класса? Зарезервированным словом default? А конструкторы классов членов вызываются?
Если не вызовешь конструктор родителя, то никак... А черт его знает...
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #36 : 10-09-2008 11:09 » 

Цитата: sss
Дак объясни наконец что такое матакласс. Никогда не пользовался.
Как известно, в типизированных языках объекты называют другими словами экземплярами классов. Метакласс - это класс классов, по отношению к которому уже классы являются экземплярами метакласса. Так сказать, класс второго порядка.

Например, в Java есть класс Class, который, как и всякий класс, является потомком класса Object, но класс Class есть такой класс, экземплярами которого являются все прочие классы (в том числе и Object, и даже сам класс Class) - т.е. класс Class фактически является метаклассом, хотя формально он тоже класс (тип данных) в языке.

Тоже самое в языках .NET: есть класс Type, экземпляры которого описывают другие классы (и могут описывать самого себя) - т.е. класс Type фактически является метаклассом, хотя формально является классом. Объекты типа Type играют важную роль в механизме reflections, при использовании которого код программы можно обрабатывать (другим кодом) как данные.

Для чего это нужно? Для того, чтобы была возможность передать информацию о типе во время исполнения как данные. В этом случае класс рассматривается не как синтаксическая конструкция времени программирования и компиляции, а как данные (экземпляр метакласса) времени исполнения со всеми нужными свойствами (в частности, ссылкой на конструктор, возможно, коллекциями ссылок на методы, свойства и т.д., перечнем реализуемых интерфейсов, ссылкой на класс-предок и т.д. - зависит от конкретного языка программирования).

Пример из .NET, аналогичный примеру из Delphi, будет таким:
Код: (Text)
using System;
using System.Reflection;

namespace Program
{
    class Program
    {
        class A
        {
            public A()
            {
                Console.WriteLine("A");
            }
        }

        class B: A
        {
            public B()
            {
                Console.WriteLine("B");
            }
        }

        static A CreateA(Type type)
        {
            // Извлекаем из описания класса информацию о его конструкторе.
            // Выбираем из всех конструкторов по их сигнатурам конструктор без параметров -
            // конструктор по умолчанию.
            Type[] constructorArgumentsTypes = new Type[0];
            ConstructorInfo constructor = type.GetConstructor(constructorArgumentsTypes);
               
            // Вызываем конструктор по умолчанию неизвестного класса и получаем объект этого
            // неизвестного класса.
            object[] constructorArguments = new object[0];
            object instance = constructor.Invoke(constructorArguments);

            // Пытаемся привести объект неизвестного класса к классу A, если неудачно, то возвращаем null.
            return instance as A;
        }

        static void Main(string[] args)
        {
            A a;

            a = CreateA(typeof(A));
            Console.ReadLine();

            a = CreateA(typeof(B));
            Console.ReadLine();
        }
    }
}

В результате получаем:

Код: (Text) Вывод программы
A

A
B

Если отказаться от приведения к A, то таким образом можно создать любой объект любого типа, но "виртуальности" конструкторов в явном виде здесь нет, в отличие от Object Pascal.

В Object Pascal конструктор нужно объявлять "виртуальным" по всей видимости лишь для того, чтобы указатель на него попал в таблицу виртуальных методов, а эта таблица используется как данные в экземпляре метакласса.

Для чего вообще передавать информацию о классах как данные? Это вопрос философский Улыбаюсь Лично я пользовался reflections только пару раз в качестве "противопожарного" средства - заплатки, когда нужно было сделать быстроее решение, а времени на перепроектирование иерархии классов не было. Может быть полезно, когда в чужой dll-ке без исходного кода определены типы, которые нельзя уже переделать, встроить в свою иерархию классов, но очень хочется - тогда можно взять reflections Улыбаюсь

Цитата: Алексей1153++
чтоб не трудно было про оба языка сразу говорить
"Оба" - это ты оптимист. Всё ещё только начинается Улыбаюсь
« Последнее редактирование: 10-09-2008 11:13 от dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #37 : 10-09-2008 11:30 » 

а я оптимист, базару нету ))
Записан

Лёха
Гость
« Ответ #38 : 12-09-2008 07:33 » 

Цитата
Сдесь на этапе компиляции не известно объект какого типа будет создаваться
expr и будет создаваться )

Ты слишком придераешся к моим словам ... ну это ладно ... 
Возможно я отступаю от темы, но всётаки кинте ссылок на тему виртуальных функций, возможно это даст мне ответы на кое какие вопросы, Спасибо.
Записан
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #39 : 12-09-2008 07:39 » new

Лёха, наздоровье.

http://lib.ru/CPPHB/cpptut.txt_with-big-pictures.html
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #40 : 12-09-2008 13:49 » 

Finch'у +1, просто супер, коротко и четко... и добавить нечего.

Лёха,
Цитата
Сдесь на этапе компиляции не известно объект какого типа будет создаваться
expr и будет создаваться )
Совершенно верно пишет пушистый, тут точно известно, что будет создаваться.

RXL,
Цитата
Сдесь на этапе компиляции не известно объект какого типа будет создаваться
expr и будет создаваться )
Метод виртуальный - в классе-потомке может быть создан другой объект. Правильнее сказать, что вызывающая метод программа не может знать, указатель на объект какого типа вернется (но точно известно, что или expr, или его потомки).
в потомке не может быть создан другой объект, не важно виртуальна ли функция или нет, как уже было сказано таблица создается/обновляется (что точно делается это личное дело компилятора) после того как отработал конструктор базового класса, поэтому отработает ровно, то что написано.
Записан

С уважением Lapulya
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #41 : 12-09-2008 15:21 » 

lapulya, опять у нас недопонимание... Ответь, пожалуйста, развернуто.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #42 : 12-09-2008 16:17 » 

Цитата: lapulya
в потомке не может быть создан другой объект, не важно виртуальна ли функция или нет, как уже было сказано таблица создается/обновляется (что точно делается это личное дело компилятора) после того как отработал конструктор базового класса, поэтому отработает ровно, то что написано.
В том примере виртуальный метод new_expr не вызывался из конструктора expr, поэтому твоё замечание в такой формулировке (привязка к порядку вызова конструкторов) бессмысленно.

Другое дело, что для создания экземпляра конкретного класса нужно иметь конкретную же фабрику, поэтому тот пример вопрос про создание произвольного объекта не решает сам по себе, а лишь позволяет вынести выбор конкретного класса создаваемого экземпляра в другую часть системы, которая на основании каких-либо данных выберет, какую конкретную фабрику создать.

Или, другими словами, фабрика (как шаблон проектирования) позволяет разделить во времени момент (и в пространстве кода место) выбора типа создаваемых объектов и момент (и место в коде) создания самих объектов.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Лёха
Гость
« Ответ #43 : 13-09-2008 11:10 » 


это ведь второе издание Страуструпа, у мну оно уже есть Жаль
там не много инфы по поводу vtbl
Записан
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #44 : 18-09-2008 15:24 » 

RXL, Сорри, я был не внимателен (с чего то придумал себе, что функция из конструктора вызывается)... все верно. И точно димка подметил, что это как правило (но далеко не всегда и на эту тебу есть и шаблон проектирования, хотя я им никогда не пользовался) выносится из класса в фабрику.
« Последнее редактирование: 18-09-2008 15:26 от lapulya » Записан

С уважением Lapulya
Страниц: 1 [2]  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines