У меня есть ощущение, что ответ будет невозможным, по крайней мере, я ничего не смог найти в этом отношении, но я надеюсь удивиться:
Я наследую и расширяю класс, предоставляемый API, расширение, которое, в свою очередь, во многом наследуется от различных производных классов, которые ранее наследовали вышеуказанную базу.
IE:
API обеспечивает theirBase
,
Пользователи обычно реализуют class myCommand: public theirBase{};
Я собрал class extendedBase: public theirBase{};
чтобы быть унаследованным вместо этого.
Это из-за повторяющихся шаблонов (чисто котельная пластина), которые я хочу удалить, и некоторых повторяющихся шагов, которые требуют особой реализации, которые я хочу сделать явно обязательными.
Если вы знакомы с Autodesk Maya, это MPxCommand, который я расширил.
Обычно, делая их чистыми виртуалами, это делается, это именно та функция, которая мне нужна, но есть загвоздка, API требует, чтобы для регистрации были реализованы статические функции обратного вызова:
static void *creator() {return new myClass;}
так что очевидно нет чистых виртуалов.
Базовая производная и функциональная команда (или команда, полученная из моего собственного специализированного суперпользователя MPxCommand) будет выглядеть примерно так:
class myCommand: public MPxCommand{
public:
myCommand(){};
virtual ~myCommand(){};
static void *creator(){ return new myCommand;} // <-- prevents pure virtual
static MSyntax syntax // M* are provided API objects/types
virtual MStatus doIt(const MArgList&);
virtual MStatus redoIt();
virtual MStatus undoIt();
protected:
boilerPlate();
virtual preflightCheck(){} // <- this I'd love to make pure, currently just warns
// currently it just warns about missing implementation
// as it should never be visible from a derived class
// and this class is purely a base
};
В настоящее время у меня нет проблем с наследованием и расширением его с помощью нескольких методов и тому подобного, но методы, которые я хочу, чтобы они были обязательно и обязательно реализованы в последующих подпрограммах (которые варьируются в зависимости от подпрограммы), могут быть только виртуальными и не чистыми (я предоставляю фиктивные реализации с предупреждение, если им звонят, указывая на невыполненную деривацию), следовательно, не гарантируя, что будущий пользователь будет знать, что он ДОЛЖЕН их реализовать, не глядя на комментарии в источнике или документ не потерял где-то, или поймает мое предупреждение в журнале, не говоря уже о У меня нет защиты времени компиляции от моей собственной глупости.
Могу ли я сделать реализацию дополнительных методов заведомо обязательной, а не чисто виртуальной?
Или какой-то способ повторно конкретизировать части класса таким образом, чтобы чистые виртуалы были исключительно приняты, несмотря на необходимость нового в статическом создателе?
GCC 4.1.2, поэтому я также оторван от многих тонкостей C ++ 11 (переопределений и тому подобного), но ради собственного образования я с радостью приму ответы, которые могут быть ожидающими того дня, когда я выиграл ». не быть привязанным к юрскому API и компилятору.
Заранее спасибо.
Вы должны иметь возможность иметь контейнеры myCommand
? Если вы этого не сделаете, вы можете получить поведение, подобное тому, которое вы ищете, сделав myCommand
в класс шаблона, где параметр шаблона будет предоставлять поведение, которое обычно идет в виртуальной функции.
template <typename PreflightChecker>
class myCommand: public MPxCommand{
public:
myCommand(){};
virtual ~myCommand(){};
static void *creator(){ return new myCommand;} // <-- prevents pure virtual
static MSyntax syntax // M* are provided API objects/types
virtual MStatus doIt(const MArgList&);
virtual MStatus redoIt();
virtual MStatus undoIt();
protected:
boilerPlate();
virtual preflightCheck()
{
PreflightChecker::check();
}
};
class MyPreflightChecker
{
public:
static void check()
{
...
}
};
vector<MPxCommand> v;
myCommand<MyPreflightChecker> command;
v.push_back(command);
Вы можете сделать это так:
class A {virtual void method() = 0 {
// now the derived classes HAS to implement it
// and you still get an implementation
}
};