Java чітко розрізняє class
та interface
. (Я вважаю, що C # так само є, але я з цим не маю досвіду). Однак при написанні C ++ немає різниці між класом та інтерфейсом, що застосовується мовою.
Отже, я завжди розглядав інтерфейс як вирішення проблеми відсутності багаторазового успадкування на Java. Здійснюючи таку різницю, у C ++ почувається довільним і безглуздим.
Я завжди схилявся до підходу "писати речі найбільш очевидним чином", тому якщо в C ++ я отримав те, що можна назвати інтерфейсом на Java, наприклад:
class Foo {
public:
virtual void doStuff() = 0;
~Foo() = 0;
};
і тоді я вирішив, що більшість реалізаторів Foo
хотів би поділитися якоюсь загальною функціональністю, напевно, я напишу:
class Foo {
public:
virtual void doStuff() = 0;
~Foo() {}
protected:
// If it needs this to do its thing:
int internalHelperThing(int);
// Or if it doesn't need the this pointer:
static int someOtherHelper(int);
};
Це робить це вже не інтерфейсом у сенсі Java.
Натомість C ++ має два важливі поняття, пов'язані з тією самою основною проблемою успадкування:
virtual
успадкуванняКласи без змінних членів не можуть займати зайвого місця при використанні в якості основи
"Суб'єкти базового класу можуть мати нульовий розмір"
З тих, кого я намагаюся уникати №1, де це можливо - рідко трапляється сценарій, коли це справді є "найчистішим" дизайном. # 2, однак, є тонкою, але важливою відмінністю між моїм розумінням терміна "інтерфейс" та мовними особливостями мови C ++. В результаті цього я (майже) ніколи не називаю речі як "інтерфейси" в C ++ і розмовляю з точки зору базових класів та їх розмірів. Я б сказав, що в контексті C ++ "інтерфейс" є неправильним.
Мені подобається, що не так багато людей роблять таке розмежування.
- Чи можу я щось втрачати, дозволяючи (наприклад
protected
) нефункціїvirtual
існувати в "інтерфейсі" в C ++? (Моє відчуття якраз протилежне - більш природне місце для спільного коду) - Чи має значення термін "інтерфейс" в C ++ - це означає лише чисте
virtual
чи було б справедливо називати класи C ++ без змінних членів інтерфейсом?
~Foo() {}
в абстрактному класі - це помилка за (майже) кожною обставиною.
internalHelperThing
можна змоделювати практично у всіх випадках.