Виртуальный деструктор для boost:noncopyable классов?

У меня есть вопрос о следующем коде:

class MyClass : private boost::noncopyable
{
    public:

    MyClass() {}
    virtual ~MyClass() {}
}

class OtherClass : private boost::noncopyable
{
    private:
    MyClass* m_pMyClass;
}

Мои мысли - то, что MyClass не может быть скопирован с помощью конструкции или присвоения. Используя виртуальный деструктор необходим, если я хочу поддерживать происходящие классы от MyClass, который я не хочу поддерживать. Я не намереваюсь создать указатели на этот класс и раздать их.

Я не хочу Singleton, и я не вижу оборотной стороны к удалению виртуального деструктора.

Я представляю потенциальную проблему, если удаляют виртуальный деструктор для noncopyable класса? Существуют ли лучшие методы для обработки класса, который не должен быть Singleton, но я только хочу один экземпляр в другом классе и не поддерживаю наследование?

8
задан TERACytE 12 January 2010 в 20:45
поделиться

5 ответов

Хотя это очень полезное, чтобы иметь, вы не можете забраться: через HAS_MANY: через отношения. Это ограничение двигателя соединения.

Альтернативы являются либо для использования COMEVER SUB-SELECT, либо в этом случае Sub-Sub Select, или намеренно денормализовать таблицы, чтобы уменьшить глубину соединения.

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

-121--3003457-

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

13
ответ дан 5 December 2019 в 05:45
поделиться

Вы говорите, что позиция содержит пустые записи последовательности... Вы действительно имеете в виду пустые последовательности, или вы имеете в виду NULL ? Если он фактически содержит записи NULL , следует использовать небольшое изменение оператора Орбмана:

SELECT * 
FROM tablename 
WHERE visible=1 
ORDER BY 
    COALESCE(position, ~0)
,   id DESC

COALESCE () возвращает значение первого аргумента, которое равно NOT NULL . ~ 0 - это часть черной магии, которая даст вам максимальное целое значение, поддерживаемое MySQL. (~ делает побитовое отрицание, превращая все 0 бит в 1). Так, в этом случае, если position IS NULL имеет значение true, то возвращается 18446744073709551615 , в противном случае возвращается значение position .

Я также хотел бы отметить, что тип данных столбца position , скорее всего, должен быть некоторого целого типа (см. http://dev.mysql.com/doc/refman/5.0/en/numeric-types.html ). Поскольку вы упоминаете пустые последовательности, я думаю, что вам следует проверить определение таблицы, выполнив команду SHOW CREATE TABLE < tablename > . Если позиция не является целым типом, я бы посоветовал вам изменить ее. Главная причина в том, что последовательности, даже если они похожи на числа, не сортируются как числа.

-121--3853800-

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

SELECT Posts.title, Categories.title 
FROM Posts, Categories, PostCategories 
WHERE PostCategories.ID_Post = Posts.ID AND PostCategories.ID_Category = Categories.ID 
ORDER BY Posts.title, Categories.title;

Получение одной строки на Пост будет немного сложнее, и будет зависеть от того, какой RDBMS вы используете.

-121--3579386-

Общее правило: если класс имеет виртуальные функции, ему необходим виртуальный деструктор. Если он не является, но по-прежнему является производным от базового класса, базовый класс (и, следовательно, ваш класс) может нуждаться или не нуждаться в виртуальном деструкторе в зависимости от этого.

Получение класса из boost:: noncopyable не считается производным от базового класса. boost:: noncopyable больше похож на удобную аннотацию с несколькими объявлениями, которые заставят компилятор применить аннотацию. Это не базовый класс в каком-либо обычном смысле. Никто никогда не попытается передать указатель на ваш класс в качестве указателя или ссылки на boost:: noncopyable . И даже если они сделали ваш виртуальный деструктор не поможет, потому что boost:: noncopyable 's destructor не является.

И, наконец, как было отмечено в комментарии, вы даже в частном порядке наследуете от boost:: noncopyable , так что это даже не действительно наследование вообще, что касается кого-либо вне класса.

На самом деле, не нужно делать его виртуальным деструктором.

9
ответ дан 5 December 2019 в 05:45
поделиться

Я действительно не поклонник усиления :: Несопируемый класс в целом. Почему бы не только объявить конструктор копирования вашего класса и оператора присваивания и не определять их. Это будет достичь то же самое, и вы можете бросить виртуальный деструктор.

Усиливание только поставляет виртуальный деструктор, чтобы люди могли пройти мимо Boost :: Несопируемые предметы полиморфные и все же оказывают ли они хорошо. Технически говоря, если вы не собираетесь использовать класс полиморфически (вы даже можете еще не наследовать от него), вам действительно не нужен виртуальный деструктор.

3
ответ дан 5 December 2019 в 05:45
поделиться

Виртуальный деструктор в базовом классе используется для того, чтобы избежать проблем с частичной разрушением, таких как:

Base *pBase = new Derived();
delete pBase; 

//if destructor is not made virtual then derived class destructor will never called.

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

Base *pBase = new Derived(); // will flash error 
3
ответ дан 5 December 2019 в 05:45
поделиться

BOOST :: Nonkopyable предназначен для того, чтобы сказать, что вы не хотите, чтобы копии объекта сделаны. Вы знаете, что это отличается от вывода из объекта.

Это совершенно нормально избавиться от виртуального деструктора, если вы никогда не получите от объекта. Если вы хотите обеспечить принуждение политики «не извлекать из этого объекта», есть способ . К сожалению, не существует BOOST :: Nonderivable , чтобы красиво это для вас.


Как уже упоминалось по ссылке, C ++ 11 позволяет объявить класс Финал :

class MyClass : final private boost::noncopyable { ... };
1
ответ дан 5 December 2019 в 05:45
поделиться
Другие вопросы по тегам:

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