2013-03-09 4 views
0

В C++ конструкторы классов могут использовать списки инициализации, о которых мне говорят, является функция производительности, которая улучшается, избегая дополнительных назначений. Поэтому мне интересно, существует ли аналогичный подход для достижения тех же преимуществ в C для функций, которые в основном служат той же цели для инициализации структур как конструкторы классов C++?Альтернативный вариант инициализации конструктора C++ в C?

Я немного не понимаю, как именно эта функция работает в компиляторе на C++, поэтому любая дополнительная информация по этому вопросу также будет оценена.

+2

Я сомневаюсь в том, что это функция исполнения. – Joe

+0

Вы можете сделать данные статичными, если хотите избежать ненужной (повторной) инициализации. – teppic

+0

@Joe - IIRC, заявка была сделана в «Основах C++» LiveLessons, но, возможно, это было неправильно, это было сделано в каком-то видеоуроке, который я смотрел. – dtech

ответ

2

В конструкторах C++ списки инициализации позволяют компилятору C++ создавать элементы-конструкторы на месте, в месте переменной-члена, вместо использования оператора присваивания, конструктора-копира или конструктора перемещения для инициализации переменной-члена. См. Section 10.6 of the C++ FAQ для более подробной информации.

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

Чтобы быть немного более ясно, что происходит, когда вы используете назначение для инициализации в C++ конструктор:

  1. Переменная член первый построен с конструктором по умолчанию
  2. временный объект построен
  3. Оператор присваивания или переноса присваивается для повторной инициализации переменной-члена с временным.
  4. Позвоните деструктору на временный.

Хотя некоторые компиляторы могут оптимизировать это в некоторых ситуациях, ваш пробег может отличаться, и ни один компилятор C++ не может оптимизировать эти шаги во всех ситуациях.Теперь рассмотрим, как программист будет точно дублировать эти шаги в C:

void my_struct_init(struct my_struct* sp) 
{ 
    member_init_default(&sp->the_member); /* default constructor for member */ 

    struct member memb; /* temporary on stack */ 
    member_init_other(&memb, ...params...); /* initialize memb */ 
    member_assign(&sp->the_member,&memb); /* assign member */ 
    member_finalize(&memb);     /* finalize the temporary */ 
} 

Немногие программисты C будут делать это (без уважительной причины). Вместо этого они будут автоматически закодировать оптимизацию:

member_init_other(&sp->the_member, ...params...); 

Функция существует в C++, поскольку компилятор делает много автоматических вещей для программиста. Это часто делает жизнь проще программисту, но требует таких функций, как списки инициализации, чтобы помочь компилятору генерировать оптимальный код. Компиляторы C представляют собой гораздо более простую модель лежащей в основе машины, делают меньше вещей автоматически и, следовательно, требуют меньше функций (хотя и не обязательно меньше работы) для создания аналогичного оптимального кода.

4

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

Больше того, что введение одной функции в язык часто создает необходимость в дополнительных функциях для усиления оригинала. Тривиальным примером являются потоки. Если потоки встроены в язык в качестве функции, тогда возникает вопрос о том, как их синхронизировать. Следовательно, необходима синхронизация. Таким образом, вы видите языки (например, C) без встроенных потоков или синхронизации и языков с обоими, но не один без другого. Здесь конструкторы относятся к потокам, поскольку синхронизация - это список инициализаторов.

+0

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

+0

В переменных C просто место в памяти, пока вы не назначите им. В C++ создаются переменные с нулевыми значениями, если это необходимо, когда они объявлены. Инициализаторы позволяют убедиться, что нулевое значение не назначено, прежде чем назначать требуемое значение. – Will

+0

Да @ Это правильно, и это именно то, что я сказал. Конструкторы на C++ - это то, где опасность множества назначений может вызвать проблему. Поскольку C не имеет конструкторов, нет никакой опасности, поэтому нет никакой необходимости в подобной инициализации. Заявления о назначении - это все, что у вас есть, и все, что вам нужно. – Gene

-1

Вы можете написать отдельную функцию и вызвать его при создании объекта из класса, а затем передать его в этом:

C:

typedef struct { 
     int x; 
}mine; 

void mine_initializer(mine* me) 
{ 
     me->x = 4; //initialization 
} 

int main(void) 
{ 
     mine me; 
     mine_initializer(&me); 
     return 0; 
} 

Также вы можете сделать это в C++:

struct mine{ 
     int x; 
     void initialize() 
     { 
       x = 4; //initialization 
     } 
}; 



void main(void) 
{ 
     mine me; 
     me.initialize(); 
     printf("%d",me.x); 
} 

В результате этого будет выводиться 4.

+0

Не совсем то, что я просил, плюс вы используете доступ к члену '.' на указателе ... – dtech

+0

@ddriver Исправлено! Oopsie! Вы хотите автоматический инициализатор? –

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