2013-06-18 3 views
2

Как вы думаете, будет ли какая-либо разница между использованием производительности/памяти в следующих двух случаях? Будет ли компилятор оптимизировать первый кусок кода, чтобы не иметь разницы между ними.const в базовом классе vs static const в производном классе

class VersionBase 
{ 
public: 
    VersionBase(int iVer) : m_iVersion(iVer) {…}; 
    int GetVersion() const { return m_iVersion; }; 
private: 
    const int m_iVersion;          
} 

class SomeVersionedDataObject : VersionBase 
{ 
    VersionedDataObject() : VersionBase(2) {…}; // Set version to whatever is the latest for the class 
    … 
    … 
} 

против

class SomeVersionedDataObject 
{ 
public: 
    VersionedDataObject() 
    int GetVersion() const { return m_iVersion; }; 
private: 
    static const int m_iVersion = 2; 
} 
+0

«Будет ли компилятор оптимизировать первую часть кода, чтобы не иметь никакого значения между этими двумя». - Возможно, в некоторых специально сконструированных тестах, но в целом, почему вы думаете, что это возможно? Они не означают одно и то же, и, по крайней мере, все, что прямо или косвенно зависит от 'sizeof (VersionBase)', будет вести себя по-другому, а * любое использование 'SomeVersionedDataObject' почти наверняка будет квалифицироваться как зависящее от' sizeof (VersionBase) '. – hvd

+0

Следует отметить, что оба они всегда инициализируются константой say '2', как в коде. Таким образом, вопрос в том, должен ли компилятор быть достаточно умным, чтобы понять, что m_iVersion будет хранить одно и то же значение для всех копий объекта, а также сделать магию и не выделять память для переменной в каждой копии объекта? (Читая это снова, я думаю, что я понял, как оптимизация компилятора работает неправильно, но тогда нет никаких глупых вопросов!) – NVM

+1

@NVM Компилятор здесь не может работать. 'sizeof (VersionBase)' должен быть одинаковым во всей программе, и ничто не мешает вам создавать экземпляр 'VersionBase' напрямую, со многими разными значениями' m_iVersion'. Невозможно переместить 'const int' из объекта. – Angew

ответ

3

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

EDIT

раствор с небольшим использованием памяти и кода двуличия будет выглядеть следующим образом:

// In one header 
template <int version> 
class VersionBase 
{ 
public: 
    int GetVersion() const { return s_version; }; 
private: 
    static const int s_version; 
}; 

template <int version> 
const int VersionBase::s_version = version; 


// Anywhere, using the header above 
class SomeVersionedDataObject : public VersionBase<2> 
{ 
    ::: 
}; 
+0

Предполагая, что у меня будет десятки тысяч экземпляров «SomeVersionedDataObject» и нескольких классов, происходящих из VersionBase (всегда инициализированных постоянным значением, которое одинаково для всех экземпляров определенного класса), есть какой-то способ его проектирования, чтобы каждый объект определенного класса не выделяет память для переменной? – NVM

+0

@NVM Да, используйте переменную static const, как в вашем втором примере. – Angew

+0

Спасибо, но тогда это было бы очень уродливо и не ремонтировалось (у меня есть сотни таких классов). Мне придется повторить один и тот же фрагмент кода во всех версированных классах. Я знаю, что вы ответили на мой вопрос, просто пытаясь понять, есть ли способ обойти это. – NVM

1

Имея себе дело с сериализации справедливый бит, я остановился на чем-то другом (и бросил наследство из окна):

inline int version(SomeVersionedDataObject const&) { return 2; } 

Отпечаток памяти соответствует значению static int const version, за исключением того, что реализация метода version может быть более умным (т. Е. Вы можете иметь версии для полиморфных классов, отправляющих метод virtual, ...).

И, конечно же, это довольно легко обеспечить версию по умолчанию для тех объектов, которые не нужны еще нет:

int version(...) { return 0; } 

Я предпочитаю его кодирования информации в некоторых базовых классов, потому что я могу продлить любой класс с ним без изменения самого класса.

+0

Это действительно блестящая идея. Одной из проблем, о которых я думал, были производные классы, содержащие их собственный номер версии, и наследование было бы проблемой. Там было бы здорово. – NVM

Смежные вопросы