Статические переменные, отдельная компиляция - PullRequest
0 голосов
/ 01 декабря 2008

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

В моем заголовке есть статическая переменная для подсчета количества объектов определенного класса. Всякий раз, когда я создаю объект, я увеличиваю эту переменную. Затем в моем деструкторе я вычитаю 1 из этой переменной, проверяю, равен ли он 0 (имеется в виду последний объект), и что-то делаю. Значение кажется выключенным иногда, я не уверен почему. У меня есть случайные звонки в моем приложении, но я не понимаю, почему это повлияет на то, что я описал выше, спасибо. Любая помощь или понимание приветствуется!

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

Я пытаюсь сделать следующее: в заголовке у меня есть следующее:

class A {
public:
    virtual ~A() {
        count --;
        if (count == 0) { /* this is the last one, do something */ }
    }

class B : public A {
public:
    B();
}

Тогда в классе B у меня есть

B::B() { 
    count++;
}

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

Ответы [ 4 ]

6 голосов
/ 01 декабря 2008

Вы должны определить конструктор в A (все они), чтобы увеличить счетчик.

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

  • Конструктор по умолчанию (если другой конструктор не определен)
  • Деструктор по умолчанию
  • Конструктор копирования
  • Оператор присваивания

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

 class A
 {
    static int count;

    public:
        A()   // Default constructor.
        {
            ++count;
        }
        A(A const& copy)  // Copy constructor/
        {                 // Note If you do not define it the compiler
            ++count;      // will automatically do it for you
        }
        virtual ~A()
        {
            --count;
            if (count == 0)
            {  // PLOP
            }
        }
        // A& operator=(A const& copy)
        // do not need to override this as object has
        // already been created and accounted for.
};

//// В исходном файле:

int A::count = 0;
1 голос
/ 01 декабря 2008

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

Убедитесь, что класс-статическая переменная определена ровно в одной единице перевода. Вы определяете это так:

int MyClass::static_var;

Это также место, куда вы положили инициализатор, если таковой имеется.

0 голосов
/ 01 декабря 2008
class A {
public:
    virtual ~A() {
        count --;
        if (count == 0) { // this is the last one, do something }
    }
protected:
    static int count;
};

class B : public A{
public:
B();
};

И затем, в один и только один из ваших исходных файлов вам нужно поместить следующее. Он должен идти в исходном файле, который содержит код для класса А.

int A::count(0);

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

0 голосов
/ 01 декабря 2008

Можете ли вы уточнить, что вы подразумеваете под "значением, кажется, выключено"? Вы получаете слишком много конструкций? Недостаточно разрушений? Если вы получите слишком много конструкций и недостаточно разрушений, это не будет иметь ничего общего со статикой.

Кроме того, что вы подразумеваете под статической переменной? Вы имеете в виду поле статического члена или фактическую статическую переменную?

Если вы объявляете просто статическую переменную в заголовке (что я сомневаюсь, что вы это делаете), то каждый файл C, который включает этот заголовок, будет иметь отдельный экземпляр этой переменной (так как static перед глобальной переменной означает, что она ограничена в этот объектный файл).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...