Почему я получаю сообщение компилятора: неопределенная ссылка на `Date::Date(int, int, int)’ [дубликат]

Вопросы и ответы

При решении задач в популярном учебнике я получил ошибку при использовании функции-члена в структуре:

…/s09-04-02.cpp:30: неопределенная ссылка на `Date::Date(int, int, int)’

// s09-04-02.cpp простая дата
#include <iostream>
struct Date {
    int y, m, d; // год
    Date(int y, int m, int d);  // объявление конструктора
    void add_day(int n);        // объявление добавления n дней
    int month() {return m;};    // определение возвращения месяца
    int day() {return d;};      // определение возвращения дня
    int year() {return y;};     // определение возвращения года
};

int main() {
    Date birthday {1970,12,30};
    std::cout<<birthday.year()<<"\n";
    std::cout<<birthday.month()<<"\n";
    std::cout<<birthday.day()<<"\n";
}
g++ -g -o s09-04-02 s09-04-02.cpp
/usr/bin/ld: /tmp/ccXgSexK.o: in function `main':
/home/c++/Stroustrup/PPandP2nd/Ch09Classes/s09-04-02.cpp:13: неопределенная ссылка на `Date::Date(int, int, int)'
collect2: ошибка: ld вернул статус выхода 1
make: *** [Makefile:5: d09-04-02] Ошибка 1

Показалось очевидным, что функция с соответствующим именем будет определена. Почему она отсутствовала, когда компоновщик искал ее?

Посмотрел несколько статей на Stack Exchange и …
Включая эту очень полную (и длинную) статью
что такое неопределенная ссылка, ошибка неразрешенного внешнего символа и как исправить

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

Вам нужно добавить это определение, например:

struct Date {
    int y, m, d;
    Date(int y, int m, int d) : y(y), m(m), d(d) {}  // объявление & определение конструктора
    ...
};

Или:

struct Date {
    int y, m, d;
    Date(int y, int m, int d);  // объявление конструктора
    ...
};

// Определение конструктора
Date::Date(int y, int m, int d)
    : y(y), m(m), d(d)
{
} 

(у вас такая же проблема и с add_day())

Ответ

Ошибка "undefined reference to Date::Date(int, int, int)" возникает из-за того, что компилятор видит объявление конструктора класса Date, но не находит его реализацию. В C++ объявление функции позволяет компилятору знать о ее существовании, но без определения (реализации) функции компилятор не может связать вызовы этой функции с ее кодом.

В вашем случае, вы объявили конструктор Date следующим образом:

Date(int y, int m, int d);  // объявление конструктора

Но не реализовали его. Это значит, что компилятор не знает, как именно следует инициализировать объект Date. По этой причине, когда линкер пытается найти реализацию конструктора, он не может ее найти, что приводит к указанной ошибке.

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

Способ 1: Объявление и реализация в одном месте

Вы можете объявить и реализовать конструктор на одном уровне в коде:

struct Date {
    int y, m, d;
    Date(int y, int m, int d) : y(y), m(m), d(d) {}  // объявление и реализация
    // остальные методы...
};

Способ 2: Отдельное объявление и реализация

Если вам нужно разделить объявление и реализацию, вы можете сделать это следующим образом:

struct Date {
    int y, m, d;
    Date(int y, int m, int d);  // объявление конструктора
    // остальные методы...
};

// реализация конструктора
Date::Date(int y, int m, int d)
    : y(y), m(m), d(d) 
{
} 

Не забудьте, что помимо конструктора Date, у вас также может быть проблема с методом add_day(int n), который вы объявили, но не реализовали. Если вы собираетесь использовать этот метод, вам также потребуется его реализация.

Пример реализации метода add_day:

void Date::add_day(int n) {
    // Здесь должна быть логика для добавления n дней к дате
    // Например, изменяем день и при необходимости корректируем месяц и год
}

Таким образом, инициализируя ваш класс с помощью полноценного определения конструктора и остальных методов, вы устраните данную ошибку линковки.

Оцените материал
Добавить комментарий

Капча загружается...