Я хочу иметь возможность совместно использовать реализацию между некоторыми, но не всеми, классами одного и того же базового класса. Я хотел бы сделать это, используя функцию множественного наследования C++ для концептуальной корректности (я знаю, что решение может заключаться в использовании композиции вместо этого).Совместное использование между классами C++
class A
{
public:
A()
{
cout << "Constructed A" << endl;
}
void DoAStuff()
{
cout << "Did A stuff" << endl;
}
};
class I : public virtual A
{
public:
I()
{
cout << "Constructed I" << endl;
}
void DoIStuff()
{
DoAStuff();
cout << "Did I stuff" << endl;
}
};
class B : public A
{
public:
B()
{
cout << "Constructed B" << endl;
}
void DoBStuff()
{
cout << "Did B stuff" << endl;
}
};
class C : public A, public I
{
public:
C()
{
cout << "Constructed C" << endl;
}
void DoCStuff()
{
cout << "Did C stuff" << endl;
}
};
class D : public A, public I
{
public:
D()
{
cout << "Constructed D" << endl;
}
void DoDStuff()
{
cout << "Did D stuff" << endl;
}
};
int main()
{
cout << "Creating a B" << endl;
B *b = new B();
cout << "Creating a C" << endl;
C *c = new C();
c->DoIStuff();
cin.ignore();
return 0;
}
В этом примере я имею BLASE класс A
и 3-х классов, которые я хочу использовать полученные из A
: B
, C
и D
.
Оба C
и D
доля общего внедрения, которые я реализовал в отдельный класс I
в DoIStuff()
. Поскольку для этой реализации необходимо сделать материал, определенный в базовом классе A
, I
также наследует A
. Ключевое слово virtual существует, так как мне нужен только один экземпляр A
при создании C
или D
.
Это все кажется красивым и выразительным мне, однако, когда я пытаюсь скомпилировать это (с помощью VC++ компилятор VS 2008) Я получаю следующие 2 ошибки:
error C2584: 'C' : direct base 'A' is inaccessible; already a base of 'I'
error C2584: 'D' : direct base 'A' is inaccessible; already a base of 'I'
Чтобы получить эту работу с множественным наследованием, добавление класса «placeholder» (например, J
), который наследует A
(но ничего не делает), и наследование D
и C
этого класса, а не непосредственно от A
, похоже, сработало. Однако этот класс placeholder делает код менее выразительным и усложняет понимание.
С другой стороны, я мог бы DoIStuff
взять параметр A
, что означает, что I
не должны наследовать от A
. Однако это означало бы, что мне придется перегружать DoIStuff
как в D
, так и в C
.
Кто-нибудь знает, какое лучшее решение для совместного использования в этом сценарии?
Я ожидал таких «ответов». Несмотря на то, что я считаю, что композиция должна быть предпочтительной по сравнению с наследованием, иерархия такова, какой она есть, и для этой «безумной» иерархии наследование оказывается более подходящим, чем композиция, на мой взгляд. – Bitbored