Как мы знаем, mixin - это шаблон проектирования, который "вставляет" некоторые поведения в другой класс. Например, в Ruby мы можем написать код, подобный этому
module Flyable
def fly
puts "I'm flying";
end
end
class Bird
include Flyable
end
C ++ не имеет поддержки смешивания на уровне языка, но мы можем использовать множественное наследование для вставки кода в производный класс. Но у этого решения все еще есть свои проблемы, такие как наследование алмазов, , неспособность переопределить виртуальный метод в интерфейсе, неспособность получить доступ к элементам из "родственных" модулей и т. Д.
Позже я обнаружил, что могу использовать макрос #include для вставки сегмента кода в определение класса для достижения смешивания:
// in Flyable.h
public:
void fly() {
// do something ...
}
float flySpeed;
И в другом файле
// in Bird.h
class Bird {
#include "Flyable.h"
};
Таким образом, все переменные-члены и функции вставляются в класс Bird.
У этого решения нет очевидного недостатка. Коды хорошо организованы в разные файлы. Возможных конфликтов имен можно избежать с помощью тщательно разработанных модулей без наложения функций / правил.
Но все же я боюсь, что есть некоторые проблемы, которые я еще не видел. Есть ли проблемы с этим типом миксина?
Редактировать
Я знаю, что использование #include внутри определения класса странно. Но это решит проблему. И программисты могут привыкнуть к этому, если он действительно используется в проекте. Итак, я хочу знать, есть ли практическая причина, по которой мы должны избегать такого кода? Не только это уродливо или странно, либо никто так не пишет.
Редактировать
Я забыл объяснить назначение кода. Вкратце, это решение проблемы алмазов без виртуального наследования. Насколько я понимаю, коренной причиной проблемы с бриллиантами является злоупотребление ООП. "Птица" - это "FlyableAnimal, FlyableAnimal" - это "Животное, Птица" - это "Плотоядное животное, Плотоядное животное" - это "Животное. Реальное намерение такого рода злоупотреблений - повторное использование кода, поэтому вместо отношений «есть» можно «лучше». И миксин может принести «-белые» отношения.
В C ++, mixin может быть достигнуто множественным наследованием. Это довольно хорошо, но это отключит полиморфизм. Например, у нас есть интерфейс Animal с чисто виртуальными функциями, и мы хотим, чтобы Bird реализовал их. Тогда мы не можем использовать множественное наследование для внедрения реализации в класс Bird. Есть несколько других методов для достижения этой цели, например, композиция. Но я не видел такого простого решения, как настоящий миксин. Вот почему я подумал о #include для mixin.