LINUX.ORG.RU

Ответ на: комментарий от Obey-Kun

> > У нас один лектор говорил, что конструкторы всегда должны быть либо виртуальными, либо защищенными (protected).

убей лектора молотком. первое не имеет отношения к C++, второе к здравому смысле.

Защищеные конструкторы очень даже имеют смысл (см. factory и синглетоны).

no-dashi ★★★★★
()
Ответ на: комментарий от no-dashi

> Если вероятность наследования от этого класса ненулевая, деструктор надо делать виртуальным. Т.е проще сказать «деструктор делать виртуальным всегда» :-)

Как-то вы лихо рубанули сплеча. Есть полно примеров, доказывающих обратное - это классы со статическими данными. Посмотрите для примера в Qt наборы отнаследованных классов от QDomNode и QStyleOption.

Dendy ★★★★★
()
Ответ на: комментарий от gizzka

Дополню. Правило номер 50: «делайте деструкторы базовых классов открытыми и виртуальными либо защищенными и невиртуальными». Герб Саттер, Андрей Александреску, «Cтандарты программирования на C++».

dave ★★★★★
()

Добавлю и я свои 5 копеек. Наличие хотя-бы одного виртуального метода, делает класс полиморфным, а следовательно добавляет поддержку RTTI(typeinfo, dynamic_cast). Это и дополнительные расходы и дополнительный функционал.

Booster ★★
()

И если конструктор приватен, то виртуальный деструктор также в общем необязателен.

Booster ★★
()
Ответ на: комментарий от Begemoth

>> И если конструктор приватен, то виртуальный деструктор также в общем необязателен.

С чего ты вдруг?


Очевидно потому что отнаследоваться от такого класса нельзя, поэтому и полиморфизм бесполезен. Но это должно быть следствием дизайна use-case самого класса.

Dendy ★★★★★
()
Ответ на: комментарий от gizzka

> один лектор говорил, что конструкторы всегда должны быть либо виртуальными, либо защищенными (protected)

конструкторы... виртуальными...


Он кретин?

one_more_hokum ★★★
()

Задачка. Имеется бинарная библиотека без исходников, только заголовочные файлы. Библиотека принимает объекты, которые создаются в пользовательском коде, которые являются производными классами некого базового класса. В этом базовом классе забыли объявить деструктор виртуальным. Библиотека самостоятельно уничтожает переданные ей объекты. Вопрос, что делать? Костыли и хаки приветствуются. ^)

Booster ★★
()
Ответ на: комментарий от Dendy

Очевидно потому что отнаследоваться от такого класса нельзя, поэтому и полиморфизм бесполезен. Но это должно быть следствием дизайна use-case самого класса.

Очевидно, унаследоваться можно:

class B;

class A
{
  A() { }

  friend class B;
};

class B : public A
{
public:
  B() { }
};
Begemoth ★★★★★
()
Ответ на: комментарий от Begemoth

>Очевидно, унаследоваться можно:
Сделать можно что угодно, но зачем? Голову ещё никто не отменял.

Booster ★★
()
Ответ на: комментарий от Dendy

И если конструктор приватен, то виртуальный деструктор также в общем необязателен.

С чего ты вдруг?

Очевидно потому что отнаследоваться от такого класса нельзя

#include <iostream>
class A {
  friend class B;
private:
  A() {}
};
class B : public A {
};
int main() {
  delete new B;
  return 0;
}
Miguel ★★★★★
()
Ответ на: комментарий от Obey-Kun

Оно работать не будет. Попробуйте произвести производный DerivedClass от вашего SomeClass. Сделайте так, чтобы SomeClass::constructThis печатал foo, а DerivedClass::constructThis печатал bar. Теперь .... следите за руками.

DerivedClass dc = new DerivedClass();

Что будет напечатано?

svu ★★★★★
()
Ответ на: комментарий от Booster

> Костыли и хаки приветствуются

Переопределить аллокатор? Использовать smart pointers?

no-dashi ★★★★★
()
Ответ на: комментарий от jtootf

И конструкторы. И операторы.

Только лямбды. Впрочем, и лямбды тоже.

svu ★★★★★
()
Ответ на: комментарий от dOzEr

хм. а что имеется ввиду под словом «виртуальный»?

azure ★★
()
Ответ на: комментарий от Booster

> Костыли и хаки приветствуются.

создай новую тему и задай там вопрос

а по делу: когда и зачем библиотека уничтожает объекты и хранит ли их? (подозреваю, что можно обернуть БазовыйКласс в умный указатель, перегрузить у него -> и добавить нужные поля и методы вместо наследования)

www_linux_org_ru ★★★★★
()

>Где лучше

в любом классе, в котором есть хоть один виртуальный метод

antony986
()
Ответ на: комментарий от gizzka

> У нас один лектор говорил, что конструкторы всегда должны быть либо виртуальными, либо защищенными (protected).

Шо?! Где учился? Фамилия ректора?

Alesh
()
Ответ на: комментарий от antony986

меня вот кстати волнует вопрос, а в каком языке реализованы виртуальные конструкторы, и зачем они нужны?

В Objective-C конструкторов нет, вместо них негласное правило запускать виртуальный метод [self init] после аллокации. Выполняет ту же роль конструктора, только в стиле обычного метода:

- (id) init
{
    if ( ![super init] )
        return 0;
    ...
    return self;
}
Dendy ★★★★★
()
Ответ на: комментарий от antony986

Более правильно так:

- (id) init 
{ 
    if ( !(self = [super init]) )
        return 0; 
    ... 
    return self; 
}

Тот же код на C++:

void * MyClass::init()
{
    if ( !BaseClass::init() )
        return 0;
    ...
    return this;
}
Dendy ★★★★★
()
Ответ на: комментарий от Dendy

короче это компенсация отсутствия обычных конструкторов?

ЗЫ. тогда уж MyClass* MyClass::init()

antony986
()
Ответ на: комментарий от antony986

виртуальные конструкторы, и зачем они нужны?

примеры можно посмотреть у GoF в описании фабричного метода

jtootf ★★★★★
()
Ответ на: комментарий от jtootf

>примеры можно посмотреть у GoF в описании фабричного метода

спасиб, нашел

antony986
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.