Здравствуйте, momart, Вы писали:
M>Есть ли виртуальные конструкторы? А деструкторы? И если есть, то зачем это надо? Спасибо.
Конструкторы нет.
Деструкторы да.
Для этого:
class a { a(){}};
class b : public a { ~b(){} };
class c { virtual ~c(){} };
class d : public d { virtual ~d(){} };
b* pb = new b;
a* pa = pb;
delete pa; // дестуктор b не вызовется !
d* pd = new d;
c* pc = pd;
delete pc; // дестуктор d вызовется
Re[2]: Бывают ли вирт. конструкторы и деструкторы?
От:
Аноним
Дата:
12.10.04 13:45
Оценка:
Здравствуйте, _nn_, Вы писали:
__>Здравствуйте, momart, Вы писали:
M>>Есть ли виртуальные конструкторы? А деструкторы? И если есть, то зачем это надо? Спасибо. __>Конструкторы нет. __>Деструкторы да. __>Для этого: __>
__>class a { a(){}};
__>class b : public a { ~b(){} };
__>class c { virtual ~c(){} };
__>class d : public d { virtual ~d(){} };
__>b* pb = new b;
__>a* pa = pb;
__>delete pa; // дестуктор b не вызовется !
__>d* pd = new d;
__>c* pc = pd;
__>delete pc; // дестуктор d вызовется
__>
интересно, как ты представляешь вызов виртуального конструктора?
Здравствуйте, momart, Вы писали:
M>Есть ли виртуальные конструкторы?
В языке нет, но есть паттерн
>А деструкторы?
есть
>И если есть, то зачем это надо?
воспользуйся, пожалуйста, поиском
здесь эти темы столько много раз обсуждали, причём очень подробно и профессионально, что просто лень писать ответ.
Re[3]: Бывают ли вирт. конструкторы и деструкторы?
От:
Аноним
Дата:
12.10.04 14:01
Оценка:
А>интересно, как ты представляешь вызов виртуального конструктора?
Скотт Мейерс под этим термином понимает что-то вроде производящей
объекты функции, которая по аргументам или как-то еще (не помню как)
создает нужный объект и возвращает указатель на базовый по отношению
к возвращаемому объекту класс.
(35 правил или способов или как-то там еще она называется)
Здравствуйте, momart, Вы писали:
M>Есть ли виртуальные конструкторы?
Нет. Есть паттерн Factory Method, который также известен под названием Virtual Constructor
Здравствуйте, Аноним, Вы писали:
А>>интересно, как ты представляешь вызов виртуального конструктора? :))
А>Скотт Мейерс под этим термином понимает что-то вроде производящей А>объекты функции, которая по аргументам или как-то еще (не помню как) А>создает нужный объект и возвращает указатель на базовый по отношению А>к возвращаемому объекту класс.
А, ну производящая объекты функция, которая по аргументам или как-то еще (не помню как) создает нужный объект и возвращает указатель на базовый по отношению к возвращаемому объекту класс, конечно же, бывает.
Здравствуйте, Аноним, Вы писали:
А>>интересно, как ты представляешь вызов виртуального конструктора?
А>Скотт Мейерс под этим термином понимает что-то вроде производящей А>объекты функции, которая по аргументам или как-то еще (не помню как) А>создает нужный объект и возвращает указатель на базовый по отношению А>к возвращаемому объекту класс.
Это обычная фабрика объектов.
Есть паттерн с таким названием. Очень полезная, кстати, штука.
Здравствуйте, momart, Вы писали:
M>Есть ли виртуальные конструкторы? А деструкторы? И если есть, то зачем это надо? Спасибо.
Наверное, в стандартном C++ виртуальных конструкторов нет, а вот в C++ Builder есть: можно посмотреть хэлп и убедиться, что львиная доля VCL-классов имеет виртуальные конструкторы (конструкторы имеют явный модификатор virtual !!!!).
Я не знаток Object Pascal, так что это не более, чем догадка: виртуальные конструкторы, я думаю, введены для совместимости с Delphi.
Объекты в создаются в Object Pascal так:
NewObject:=TType.Create;
или так
var FisrtObject:TType;
...
NewObject:=FirstObject.Create; // надеюсь, не ошибаюсь
Соответственно, если в классах TBase и TDerived имеются виртуальные конструкторы Create, то может быть так:
var
Base:TBase;
Derived:TDerived;
NewObject:TBase;
begin
Derived:=TDerived.Create;
Base:=Derived;
NewObject:=Base.Create;
Соответственно, NewObject будет содержать ссылку на TDerived
Здравствуйте, Dr.Gigabit, Вы писали:
DG>Здравствуйте, momart, Вы писали:
M>>Есть ли виртуальные конструкторы?
DG>Кажется, Страуструп по этому поводу пишет так: "Нет, но легко достичь желаемого эффекта" DG>Как там говорят частенько: учите матчасть
Лажа все это. если ты создаешь объект, то ты вызываешь его конструктор. Если конструктор виртуальный, это значит ты создаешь объект а вызываешь перегруженный конструктор класса потомка — что является полным бредом, поскольку если тебе нужен потомок то его и создавай.
Re[2]: Бывают ли вирт. конструкторы и деструкторы?
Здравствуйте, AdUser, Вы писали:
AU>Я не знаток Object Pascal, так что это не более, чем догадка: виртуальные конструкторы, я думаю, введены для совместимости с Delphi.
Еще виртуальные конструкторы в Builder'е позволяют осуществлять динамическую диспетчеризацию виртуальных функций-членов, вызванных из конструктора. Например:
class Base
{
virtual void DoSomething();
virtual Base();
};
class Derived
{
virtual void DoSomething();
virtual Derived();
}
Base::Base()
{
// Если создается объект класса Base, то будет вызван Base::DoSomething()
// Если создается объект класса Derived, то вызывается Derived::DoSomething()
// В стандартном C++ в обоих случаях вызывается Base::DoSomething()
DoSomething();
}
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Re[3]: Бывают ли вирт. конструкторы и деструкторы?
Здравствуйте, Эдик, Вы писали:
Э>Здравствуйте, AdUser, Вы писали:
AU>>Я не знаток Object Pascal, так что это не более, чем догадка: виртуальные конструкторы, я думаю, введены для совместимости с Delphi.
Э>Еще виртуальные конструкторы в Builder'е позволяют осуществлять динамическую диспетчеризацию виртуальных функций-членов, вызванных из конструктора. Например: Э>
Э>class Base
Э>{
public:
Э> virtual void DoSomething();
Э> virtual Base();
Э>};
Э>class Derived : public Base
Э>{
public:
Э> virtual void DoSomething();
Э> virtual Derived();
Э>};
Э>Base::Base()
Э>{
Э> // Если создается объект класса Base, то будет вызван Base::DoSomething()
Э> // Если создается объект класса Derived, то вызывается Derived::DoSomething()
Э> // В стандартном C++ в обоих случаях вызывается Base::DoSomething()
Э> DoSomething();
Э>}
Э>
Предположим, что в вышенаписанном коде все-таки забыли дописать куски, выделенные жирным.
Тогда назревает вопрос. Что будет, если DoSomething обращается к каким-то членам класса Derived, которые еще не были инициализированы? Ведь конструктор Base::Base() вызовется из Derived::Derived() до инициализации каких-либо членов самого Derived? И зачем вообще такой изврат нужен (имеется в виду виртуальный конструктор)? С примером если можно.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Re[2]: Бывают ли вирт. конструкторы и деструкторы?
AU>Наверное, в стандартном C++ виртуальных конструкторов нет, а вот в C++ Builder есть: можно посмотреть хэлп и убедиться, что львиная доля VCL-классов имеет виртуальные конструкторы (конструкторы имеют явный модификатор virtual !!!!).
Если это наследники TObject
Я в Delphi часто использую виртуальные конструкторы совместно с типами — ссылками на класс. Например, есть набор объектов, которые хранят ссылки на классы — редакторы этих объектов. Если все классы редакторов имеют общего предка и этот предок имеет виртуальный конструктор, которые перекрываются в наследниках и обеспечивают необходимую инициализацию, то я могу имея ссылку на класс просто вызвать виртуальный конструктор от него, не думая, какой класс будет создан.
Вот пример:
type
TAbstractEditor = class
constructor Create; virtual;
procedure Edit( const AItem : TItem ); virtual;
end;
TAbstractEditorClass = class of TAbstractEditor;
TItem = class
...
function GetEditorClass : TAbstractEditor; virtual;
...
end;
TMyEditor = class( TAbstractEditor )
constructor Create; virtual;
procedure Edit( const AItem : TItem ); virtual;
end;
var
oItem : TItem;
begin
... // здесь где-то есть инициализация oItem
// А здесь вызов вируального конструктора редактораwith oItem.GetEditorClass.Create do
Edit( oItem );
end
Здравствуйте, momart, Вы писали:
M>Есть ли виртуальные конструкторы? А деструкторы? И если есть, то зачем это надо? Спасибо.
Я так думаю, проблема виртуальных конструкторов как и виртуальных статических методов проиcходит из того, что в плюса нет рантайм понятия обьект-класса.
Я, например, могу себе представить вызов виртуального конструктора и виртуального статического метода очень просто.
class T{
public :
virtual T();
static virtual static_fn();
};
class X : public T {
virtual X();
static virtual static_fn();
};
void any_func(class_ref<T> MT) {
T* t = new MT;
MT::static_fn();
}
void main() {
any_func(X);
}
Собственно, вот . Проблема только в том, что в рантайме/языке такого нет, но нечто подобное есть в статике.
Re[4]: Бывают ли вирт. конструкторы и деструкторы?
Здравствуйте, Peregrin, Вы писали:
P>Здравствуйте, Эдик, Вы писали:
Э>>Здравствуйте, AdUser, Вы писали:
P>Предположим, что в вышенаписанном коде все-таки забыли дописать куски, выделенные жирным.
P>Тогда назревает вопрос. Что будет, если DoSomething обращается к каким-то членам класса Derived, которые еще не были инициализированы? Ведь конструктор Base::Base() вызовется из Derived::Derived() до инициализации каких-либо членов самого Derived? И зачем вообще такой изврат нужен (имеется в виду виртуальный конструктор)? С примером если можно.
Зачем нужен, например для того чтобы сделать как в Дельфи: обработчик события OnCreate формы TMyForm вызывается до вызова сонструктора TMyForm.
Что будет, если вы обратитесь к неинициализированным членам TMyForm? Старая грабля — как правило ничего не бывает, ни матов компилятора, ни аварийного завершения программы... Вот только инициализация в конструкторе дефолтными значениями будет предшествовать инициализации (или обращению) в обработчике OnCreate... Когда я впервый раз на это наткнулся очень сильно удивился!
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Re[5]: Бывают ли вирт. конструкторы и деструкторы?
Здравствуйте, Mr. None, Вы писали:
MN>Здравствуйте, Peregrin, Вы писали:
P>>Здравствуйте, Эдик, Вы писали:
Э>>>Здравствуйте, AdUser, Вы писали:
P>>Предположим, что в вышенаписанном коде все-таки забыли дописать куски, выделенные жирным.
P>>Тогда назревает вопрос. Что будет, если DoSomething обращается к каким-то членам класса Derived, которые еще не были инициализированы? Ведь конструктор Base::Base() вызовется из Derived::Derived() до инициализации каких-либо членов самого Derived? И зачем вообще такой изврат нужен (имеется в виду виртуальный конструктор)? С примером если можно.
MN>Зачем нужен, например для того чтобы сделать как в Дельфи: обработчик события OnCreate формы TMyForm вызывается до вызова сонструктора TMyForm. MN>Что будет, если вы обратитесь к неинициализированным членам TMyForm? Старая грабля — как правило ничего не бывает, ни матов компилятора, ни аварийного завершения программы... Вот только инициализация в конструкторе дефолтными значениями будет предшествовать инициализации (или обращению) в обработчике OnCreate... Когда я впервый раз на это наткнулся очень сильно удивился!
навороты в зоопарке. хочешь вызывать метод без объекта — сделай его статик.
Re[4]: Бывают ли вирт. конструкторы и деструкторы?
Здравствуйте, Alexey Chen, Вы писали:
AC>Здравствуйте, Аноним, Вы писали:
А>>интересно, как ты представляешь вызов виртуального конструктора? AC>Как вызов метода метакласса.
Да, например в Delphi есть виртуальные конструкторы и понятие метакласса