fopen () в S-функции: ошибка компиляции [дубликат]

Члены класса:

Для деструктора pure virtual требуется реализация.

Объявление деструктора по-прежнему требует определения его (в отличие от обычной функции):

struct X
{
    virtual ~X() = 0;
};
struct Y : X
{
    ~Y() {}
};
int main()
{
    Y y;
}
//X::~X(){} //uncomment this line for successful definition

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

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

Это похоже на методы не virtual без определения, с добавлением аргументов, которые генерирует чистая декларация dummy vtable, и вы можете получить ошибку компоновщика без использования функции:

struct X
{
    virtual void foo();
};
struct Y : X
{
   void foo() {}
};
int main()
{
   Y y; //linker error although there was no call to X::foo
}

Чтобы это сработало, объявите X::foo() чистым:

struct X
{
    virtual void foo() = 0;
};

Non- virtual

Некоторые члены должны быть определены, даже если они явно не используются:

struct A
{ 
    ~A();
};

Следующие ошибки приведут к ошибке:

A a;      //destructor undefined

Реализация может быть встроенной в самом определении класса:

struct A
{ 
    ~A() {}
};

или снаружи:

A::~A() {}

Если реализация вне определения класса, но в заголовке, методы должны быть отмечены как inline, чтобы предотвратить множественное определение.

Все используемые методы-члены должны быть определены, если они используются.

Общей ошибкой является отказ от квалификации имени:

struct A
{
   void foo();
};

void foo() {}

int main()
{
   A a;
   a.foo();
}

Определение должно быть

void A::foo() {}

static. Члены данных должны быть определены вне класса в единственная единица перевода:

struct X
{
    static int x;
};
int main()
{
    int x = X::x;
}
//int X::x; //uncomment this line to define X::x

Инициализатор может быть предоставлен для элемента данных static const типа интеграла или перечисления в определении класса; однако odr-использование этого элемента по-прежнему потребует определения области пространства имен, как описано выше. C ++ 11 позволяет инициализировать внутри класса для всех членов static const данных.

48
задан Peter Mortensen 16 January 2014 в 16:42
поделиться

4 ответа

Я думаю, вы должны переместить объявление переменной в начало блока. I.e.

{
    foo();
    int i = 0;
    bar();
}

-

{
    int i = 0;
    foo();
    bar();
}
83
ответ дан Johan Kotlinski 26 August 2018 в 19:02
поделиться

Просто используйте компилятор (или предоставите ему необходимые ему аргументы), чтобы он компилировался для более новой версии стандарта C, C99 или C11. Например, для компиляторов семейства GCC, которые будут -std=c99.

10
ответ дан 2 revs, 2 users 67% 26 August 2018 в 19:02
поделиться

До стандарта C99 все объявления приходили перед любыми утверждениями в блоке:

void foo()
{
  int i, j;
  double k;
  char *c;

  // code

  if (c)
  {
    int m, n;

    // more code
  }
  // etc.
}

C99 разрешено смешивать объявления и утверждения (например, C ++). Многие компиляторы по-прежнему используют C89, а некоторые компиляторы (например, Microsoft) не поддерживают C99 вообще .

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

  1. Определить, поддерживает ли ваш компилятор C99 или новее; если это так, настройте его так, чтобы он компилировал C99 вместо C89;
  2. Если ваш компилятор не поддерживает C99 или более позднюю версию, вам нужно будет найти другой компилятор, который делает поддерживать его или переписывать свой код, чтобы все объявления приходили перед любыми операторами внутри блока.
21
ответ дан John Bode 26 August 2018 в 19:02
поделиться

Чтобы диагностировать, что действительно вызывает ошибку, я бы сначала попытался удалить = 0

  • Если ошибка сработала, то, скорее всего, декларация идет после кода.
  • Если нет ошибки, то это может быть связано с C-стандартными флагами принудительного исполнения / компиляции OR ... что-то еще.

В любом случае объявите переменную в начале текущий объем. Затем вы можете инициализировать его отдельно. Действительно, если эта переменная заслуживает своей собственной области действия - разделите ее определение на {}.

Если OP может прояснить контекст, тогда последует более направленный ответ.

3
ответ дан Peter Mortensen 26 August 2018 в 19:02
поделиться
Другие вопросы по тегам:

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