Несколько экземпляров класса с постоянными переменными используют одну и ту же память для констант? - PullRequest
4 голосов
/ 21 октября 2011

Если у меня есть класс, который определяет несколько константных переменных, например ...

class SomeClass {
public:
    SomeClass() : SOME_CONSTANT(20), ANOTHER_CONSTANT(45), ANOTHER_CONSTANT2(25), ANOTHER_CONSTANT2(93) { }

private:
    const int SOME_CONSTANT;
    const int ANOTHER_CONSTANT;
    const int ANOTHER_CONSTANT2;
    const int ANOTHER_CONSTANT3;

Будут ли оптимизированы несколько экземпляров этого класса, чтобы указывать на одну и ту же память для констант?или я могу сохранить память, сделав каждую константу статической?

Ответы [ 5 ]

5 голосов
/ 21 октября 2011

Если они не являются статичными, то нет, они не будут оптимизированы. В каждом экземпляре будет место для всех констант. (На самом деле, я не думаю, что компилятору даже разрешено комбинировать их каким-либо образом.)

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

EDIT:

Если вы хотите сделать их статическими константами, это должно быть сделано так:

class SomeClass {
    public:
        SomeClass(){ }

    private:
        static const int SOME_CONSTANT;
        static const int ANOTHER_CONSTANT;
        static const int ANOTHER_CONSTANT2;
        static const int ANOTHER_CONSTANT3;

};

const int SomeClass::SOME_CONSTANT     = 20;
const int SomeClass::ANOTHER_CONSTANT  = 45;
const int SomeClass::ANOTHER_CONSTANT2 = 25;
const int SomeClass::ANOTHER_CONSTANT3 = 93;
3 голосов
/ 21 октября 2011

А как насчет перечисления?

class SomeClass {
public:
    SomeClass() { }

private:
    enum {
        SOME_CONSTANT = 20,
        ANOTHER_CONSTANT = 45,
        ANOTHER_CONSTANT2 = 25,
        ANOTHER_CONSTANT3 = 93
    };
};

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

1 голос
/ 21 октября 2011

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

Примечание: не забудьте определить их вне класса. Так как это int s, вы можете избежать их определения вне класса, на самом деле это зависит больше от компилятора, чем от стандарта (да, я знаю, насколько нелепо это звучит). Сейчас я не могу это проверить, но я помню, что gcc и VS ведут себя по-разному.

Итак, вам может потребоваться сделать следующее:

class SomeClass {
public:
    SomeClass()
    { }

private:
    static const int SOME_CONSTANT;
    static const int ANOTHER_CONSTANT;
    static const int ANOTHER_CONSTANT2;
    static const int ANOTHER_CONSTANT3;

const int SomeClass::SOME_CONSTANT = 20;
//.. the same for the others.

РЕДАКТИРОВАТЬ Я найду эту часть стандарта (исключение для целочисленных типов) и опубликую ее здесь + тесты на обоих компиляторах позже сегодня :))

0 голосов
/ 21 октября 2011

Вы не можете сделать эти константы статичными - просто потому, что ваш конструктор их инициализирует!

SomeClass() : SOME_CONSTANT(20), ANOTHER_CONSTANT(45), ANOTHER_CONSTANT2(25), ANOTHER_CONSTANT2(93) { }

Удалите эти инициализаторы, т.е.

SomeClass{};
static const int SOME_CONSTANT = 20;

Тогда у вас будет только один int длякласс.

0 голосов
/ 21 октября 2011

Вы можете попробовать проверить sizeof () экземпляра класса.Я не думаю, что они будут оптимизированы.Использование статических переменных const для этой цели, вероятно, будет правильным решением, особенно если они все являются целыми числами, и в этом случае вы можете инициализировать их в определении и получить константы времени компиляции, не беспокоясь о порядке инициализации статических объектов.

class SomeClass
{
private:
    const static int SOME_CONSTANT     = 20;
    const static int ANOTHER_CONSTANT  = 45;
    const static int ANOTHER_CONSTANT2 = 25;
    const static int ANOTHER_CONSTANT3 = 93;
};
...