Как инициализировать статическую структуру в C ++? - PullRequest
9 голосов
/ 18 апреля 2011

Мне удалось правильно инициализировать любую переменную базового типа (например, int, char, float и т. Д.), Но при объявлении небольшой сложной переменной все, что я вижу, это ошибки.

В файле заголовка timer.hiобъявлять

class AndroidTimerConcept {
...
private:
    //struct that holds the necessary info for every event
    struct Resources{
        timer_delegate_t membFunct;
        void *data;
        int size;
        millis_t time;
    };
    //declaring an array of 10 Resources structs
    static struct Resources ResData;
    static int best;
...
}

в файле timer.cpp

#include <iostream>
#include "timer.h"
using namespace std;


int AndroidTimerModel::best=1000;
struct Resources AndroidTimerModel::ResData.size; //line 17!!
//constructor that initializes all the necessary variables

AndroidTimerModel::AndroidTimerModel()
{
    signal(SIGALRM,signalHandler);

    for(int i=0; i<MAX_EVENTS; i++)
    {
        //ResData.data=NULL;
        ResData.size=-1;
        //ResData.time=-1;
    }

    best=1000;

}

при компиляции файла .cpp я получаю сообщение об ошибке: timer.cpp: 7: ошибка: ожидаемый инициализатор перед '.'маркер

Любые предложения будут очень полезны.

кстати я использую g ++

Ответы [ 6 ]

6 голосов
/ 18 апреля 2011

Вы не можете отдельно определять отдельные элементы экземпляра в статическом члене.

Этого должно быть достаточно:

AndroidTimerModel::Resources AndroidTimerModel::ResData;
5 голосов
/ 18 апреля 2011

Вы можете использовать инициализатор структуры в C ++, но только в стиле до C99 (т.е. вы не можете использовать назначенные инициализаторы). Назначенные инициализаторы , которые позволяют указывать инициализируемые элементы по имени, а не полагаться на порядок объявления, были введены в C99, но в настоящее время не являются частью какого-либо стандарта C ++ (опровергая общееПредположение, что C ++ является надмножеством C).

Если вы хотите написать непереносимый код C ++, который специально предназначен для g ++, вы всегда можете использовать специфичное для GCC расширение , которое имеетта же функциональность, что и для обозначенных конструкторов.Синтаксис выглядит следующим образом:

struct value_t my_val = { member_a: 1, member_b: 1.2f };

Эта ссылка предоставляет довольно хороший обзор обоих типов инициализации в контексте C.

Вот выдержка, которая показывает как более ранние (без указателей), так и стили C99:

При инициализации структуры первый инициализатор в списке инициализирует первый объявленный элемент(если не указан указатель) (начиная с C99) и все последующие инициализаторы без указателей (начиная с C99) инициализируют элементы структуры, объявленные после элемента, инициализированного предыдущим выражением.

struct point {double x,y,z;} p = {1.2, 1.3}; // p.x=1.2, p.y=1.3, p.z=0.0
div_t answer = {.quot = 2, .rem = -1 };      // order of elements in div_t may vary

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

struct Resources AndroidTimerModel::ResData = function_that_acts_like_a_constructor();
1 голос
/ 18 апреля 2011

Вам необходимо объявить и определить конструктор для структуры Resources. например,

struct Resources{
    timer_delegate_t membFunct;
    void *data;
    int size;
    millis_t time;
    Resources():membFunct(0), data(0), size(0), time(0) {}
    ....
};
0 голосов
/ 18 апреля 2011

Является ли это AndroidTimerModel или AndroidTimerConcept, вы не можете использовать разные имена и ожидать, что компилятор будет думать, что они одно и то же.в области действия класса AndroidTimerModel:

AndroidTimerModel::Resources AndroidTimerModel::ResData;

Я предлагаю вам дать Ресурсу конструктор:

struct Resources{
    Resources(timer_delegate_t aMembFunct, void* aData, int aSize, millis_t aTime )
      : membFunc(aMembFunct)
      , data(aData)
      , size(aSize)
      , time(aTime)
    {}
    timer_delegate_t membFunct;
    void *data;
    int size;
    millis_t time;
};

И затем вы можете определить Res в вашем .cpp как:

AndroidTimerModel::Resources AndroidTimerModel::ResData(/* params here */);
0 голосов
/ 18 апреля 2011

Вам нужно инициализировать переменную whole , примерно так:

AndroidTimerConcept::Resources AndroidTimerModel::ResData = { NULL, NULL, 0, 0 };
0 голосов
/ 18 апреля 2011

Почему ваша struct часть класса?Я бы сделал его глобальным за пределами класса.

memset(&structname, 0, sizeof(structname)); инициализирует вашу структуру до 0.

...