При каких обстоятельствах выгодно дать реализацию чистой виртуальной функции?

Получить позицию первого пробела:

int space1 = theString.IndexOf(' ');

Положение следующего пробела после этого:

int space2 = theString.IndexOf(' ', space1 + 1);

Получить часть строки до второго пробела. :

string firstPart = theString.Substring(0, space2);

Приведенный выше код помещает вместе в одну строку:

string firstPart = theString.Substring(0, theString.IndexOf(' ', theString.IndexOf(' ') + 1));
28
задан adl 10 January 2012 в 10:29
поделиться

6 ответов

Declared destructors must always be implemented as the implementation will call them as part of derived object destruction.

Other pure virtual functions may be implemented if they provide a useful common functionality but always need to be specialized. In the case, typically derived class implementations will make an explicit call to the base implementation:

void Derived::f()
{
    Base::f();

    // Other Derived specific functionality
}

Typically, you make a destructor virtual if you need to make a class abstract (i.e. prevent non-derived instances from being created) but the class has no other functions that are naturally pure virtual. I think the 'trust me it's faster' is refering to the fact that because destructors called as part of derived object clean up don't need to use a vtable lookup mechanism, the inline implementation can be taken advantage of, unlike typical virtual function calls.

23
ответ дан 28 November 2019 в 03:42
поделиться

Если у вас такие общие функциональность, которую может использовать производный класс. Но им нужно выполнять и другую работу.

Итак, производный класс реализует виртуальную функцию и вызывает базовую версию:

class X: public C
{
    public:
        virtual int f()
        {
            return C::f() + 1; // I am +1 over my parent.
        }
};
4
ответ дан 28 November 2019 в 03:42
поделиться

Только что узнал, что Херб Саттер ответил на первую часть этого вопроса в своем Гуру недели № 31 .

4
ответ дан 28 November 2019 в 03:42
поделиться

Чтобы обеспечить определенный порядок обработки свойств объекта в цикле for-in, вам необходимо определить порядок сортировки или метод списка для объекта. Если вы определяете все свойства при создании объекта, подойдет массив имен свойств, но если вы можете добавлять или удалять свойства, требуется метод.

Если порядок обработки важен по какой-либо причине, массив может быть предпочтительнее.

Скотт Мейерс обсуждает это в своей книге «Эффективный C ++». Это пункт 36 в первом издании.

HTH

ура,

2
ответ дан 28 November 2019 в 03:42
поделиться

Потому что писать:

class Funct {
public:
  virtual int doit(int x) = 0;
  virtual ~Funct() = 0 {};
};

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

class Funct {
public:
  virtual int doit(int x) = 0;
  virtual ~Funct() {};
};

Класс по-прежнему будет абстрактным, поскольку по крайней мере один метод является чисто виртуальным. Деструктор также остается встроенным.

0
ответ дан 28 November 2019 в 03:42
поделиться

Что касается скорости виртуального деструктора, это связано с тем, что деструктор определен в файле cpp, а не в заголовке. Это больше связано с размером, чем со скоростью. Это подробно объясняется в «Крупномасштабном проектировании программного обеспечения C ++». К сожалению, я не могу вспомнить все детали, но я думаю, что встроенные виртуальные функции определяются в vtable несколько раз.

Здесь обсуждается: Действительно ли встроенные виртуальные функции бессмысленны?

0
ответ дан 28 November 2019 в 03:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: