Множественное определение функции (в производном классе) [дубликат]

В одном из операторов INSERT вы пытаетесь вставить слишком длинную строку в столбец строки [varchar или nvarchar).

Если не очевидно, что INSERT злоумышленник простым взглядом на скрипт, вы можете считать строки <1 row affected>, которые появляются перед сообщением об ошибке. Полученный номер плюс один дает вам номер выписки. В вашем случае это, по-видимому, второй INSERT, который вызывает ошибку.

23
задан Keith Pinson 11 February 2013 в 21:19
поделиться

4 ответа

Проблема заключается в том, что следующий фрагмент кода - это определение, а не объявление:

std::ostream& operator<<(std::ostream& o, const Complex& Cplx) {
   return o << Cplx.m_Real << " i" << Cplx.m_Imaginary;
}

Вы можете либо отметить функцию выше, и сделать ее «встроенной», чтобы несколько единиц перевода могли определять it:

inline std::ostream& operator<<(std::ostream& o, const Complex& Cplx) {
   return o << Cplx.m_Real << " i" << Cplx.m_Imaginary;
}

Или вы можете просто перенести исходное определение функции в исходный файл «complex.cpp».

Компилятор не жалуется на «real () «потому что он неявно встроен (любая функция-член, чье тело указана в объявлении класса, интерпретируется так, как если бы она была объявлена« встроенной »). Предохранители препроцессора предотвращают включение вашего заголовка более одного раза из одной единицы перевода («* .cpp» исходного файла »). Однако обе единицы перевода видят один и тот же заголовочный файл. В основном компилятор компилирует« main.cpp »в «main.o» (включая любые определения, указанные в заголовках, включенных в «main.cpp»), и компилятор отдельно компилирует «complex.cpp» в «complex.o» (включая любые определения, указанные в заголовках, включенных в «сложный» .cpp "). Затем компоновщик объединяет« main.o »и« complex.o »в один двоичный файл, и именно в этот момент компоновщик находит два определения для функции с тем же именем. что линкер пытается разрешить внешние ссылки (например, «main.o» относится к «Complex :: Complex», но не имеет определения для этой функции ... компоновщик находит определение из «complex.o» и разрешает эта ссылка).

37
ответ дан Michael Aaron Safyan 31 August 2018 в 19:24
поделиться

И есть ли другое решение с использованием ключевого слова inline?

Да, есть.

namespace {
    std::ostream& operator<<(std::ostream& o, const Complex& Cplx) {
        return o << Cplx.m_Real << " i" << Cplx.m_Imaginary;
    }
}

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

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

6
ответ дан Konrad Rudolph 31 August 2018 в 19:24
поделиться

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

Оказалось, что Eclipse использовал устаревшие артефакты из предыдущей (неудачной) сборки.

Чтобы исправить, используйте Project > Clean, затем перестройте.

0
ответ дан PaulrBear 31 August 2018 в 19:24
поделиться

Переместить реализацию в complex.cpp

. Прямо сейчас после включения этого файла реализация компилируется в каждый файл. Позже во время связывания существует очевидный конфликт из-за повторяющихся реализаций.

:: real () не сообщается, потому что это неявно (реализация внутри определения класса)

5
ответ дан XAder 31 August 2018 в 19:24
поделиться
Другие вопросы по тегам:

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