Не удается получить откат родителей вложенных транзакций в Rspec for Rails

Почему forward-declare необходимо в C ++

Компилятор хочет убедиться, что вы не допустили орфографических ошибок или передали неправильное количество аргументов функции. Таким образом, он настаивает на том, что сначала он видит объявление «добавить» (или любые другие типы, классы или функции) до его использования.

Это действительно позволяет компилятору лучше выполнять проверку правильности кода, и позволяет ему убирать свободные концы, чтобы он мог создавать аккуратно выглядящий объектный файл. Если вам не нужно было пересылать объявления, компилятор создаст объектный файл, который должен содержать информацию обо всех возможных догадках относительно функции «добавить». И компоновщик должен будет содержать очень умную логику, чтобы попытаться определить, какую «добавленную» вы на самом деле намеревались вызывать, когда функция «добавить» может жить в другом объектном файле, компоновщик соединяется с тем, который использует add для создания dll или exe. Вполне возможно, что компоновщик может ошибиться. Предположим, вы хотели использовать int add (int a, float b), но случайно забыли написать его, но компоновщик нашел уже существующий int add (int a, int b) и подумал, что это был правильный, и вместо этого использовал это. Ваш код будет скомпилирован, но не будет делать то, что вы ожидали.

Итак, просто для того, чтобы держать вещи явными и избегать гадания и т. Д., Компилятор настаивает на том, что вы объявляете все до его использования.

Разница между объявлением и определением

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

Как передовые объявления могут значительно сократить время сборки

Вы можете получить объявление функции в ваш текущий .cpp или .h файл #, включающий заголовок, который уже содержит объявление функции. Однако это может замедлить компиляцию, особенно если вы # включите заголовок в .h вместо .cpp вашей программы, так как все, что # включает в себя .h, которое вы пишете, будет включать # include'все все заголовки вы написали #includes for too. Внезапно компилятор имеет # вложенные страницы и страницы кода, которые он должен компилировать, даже если вы только хотели использовать одну или две функции. Чтобы этого избежать, вы можете использовать форвардную декларацию и просто вводить декларацию функции самостоятельно в верхней части файла. Если вы используете только несколько функций, это может сделать ваши компиляции быстрее по сравнению с всегда # включая заголовок.

Разрыв циклических ссылок, где два определения используют друг друга

Кроме того, пересылка вперед -declarations может помочь вам сломать циклы. Здесь две функции пытаются использовать друг друга. Когда это происходит (и это совершенно правильная вещь), вы можете # включить один заголовочный файл, но этот заголовочный файл пытается # включить заголовочный файл, который вы сейчас пишете .... который затем # включает другой заголовок , который # включает тот, который вы пишете. Вы застряли в ситуации с курятиной и яйцом, каждый заголовочный файл пытается повторно включить #include. Чтобы решить эту проблему, вы можете переслать-заявить части, которые вам нужны в одном из файлов, и оставить #include из этого файла.

Например:

Файл Car.h

#include "Wheel.h"  // Include Wheel's definition so it can be used in Car.
#include <vector>

class Car
{
    std::vector<Wheel> wheels;
};

File Wheel.h

Хмм ... Объявление автомобиля требуется здесь, поскольку Wheel имеет указатель на автомобиль, но Car.h не может быть включен здесь как это приведет к ошибке компилятора. Если бы Car.h был включен, это попыталось бы включить Wheel.h, который будет включать Car.h, который будет включать Wheel.h, и это будет продолжаться вечно, поэтому вместо компилятора возникает ошибка. Решение состоит в том, чтобы переслать объявление Car вместо:

class Car;     // forward declaration

class Wheel
{
    Car* car;
};

Если у класса Wheel были методы, которые необходимо вызвать методы автомобиля, эти методы могут быть определены в Wheel.cpp, а Wheel.cpp теперь может включать Car.h, не вызывая цикл.

0
задан Thermatix 25 March 2019 в 18:04
поделиться