ODR (One Definition Rule) – это правило одной определения в C++, которое запрещает множественное определение одной и той же сущности в программе.
ODR применяется к:
Переменным
Функциям
Классам
Если ODR нарушено, получим ошибку компоновки (linker error, multiple definition).
🚩Основные правила ODR
Переменная может быть определена только один раз
// a.cpp
int x = 42; // Определение переменной
// b.cpp
int x = 42; // ❌ Ошибка компоновки: повторное определение x
Решение: Использовать
extern в заголовочном файле. // common.h
extern int x; // Объявление
// a.cpp
#include "common.h"
int x = 42; // Определение (только в одном месте)
// b.cpp
#include "common.h"
Функция может быть определена только один раз (если не
inline) // a.cpp
void foo() { } // Определение функции
// b.cpp
void foo() { } // ❌ Ошибка: повторное определение
Решение: Использовать
inline или объявить в header, но определить в .cpp. // common.h
inline void foo() { } // ✅ OK, `inline` разрешает множественные определения
Класс можно определить только один раз
// a.h
struct A {
int x;
};
// a.h включён в два файла -> ❌ Ошибка "redefinition of struct A"
Решение: Использовать
#pragma once или #ifndef // a.h
#pragma once // ✅ Защита от двойного включения
struct A {
int x;
};
constexpr нарушает ODR при разных значениях // common.h
constexpr int getValue() { return 10; }
// a.cpp
int a = getValue(); // 10
// b.cpp
constexpr int getValue() { return 20; } // ❌ Ошибка: разные определения
Ставь 👍 и забирай 📚 Базу знаний