У меня есть родительский класс с не виртуальным интерфейсом (NVI):
class Parent {
private:
virtual int do_function(void) = 0;
public:
int function(void);
virtual ~Parent() {};
}
И дочерний класс (на самом деле, у меня много дочерних классов, но я хочу, чтобы только этот работал таким образом)
class Child : public Parent {
private:
int _x;
int do_function(void) { return _x; };
public:
Child(int x): Parent(), _x(x) {}
virtual ~Child() {return do_function();};
}
И я хочу вызвать функцию:
int myFunction(Parent& x) {
return x.function();
}
используя код
int x = 5;
myFunction(x);
но не
int myFunction(const Child& x) {
return x.function();
}
который отлично работает
Можно ли сделать это с неявным преобразованием типов?
По сути, вы хотите неявно создать дочерний объект, созданный с помощью x, а затем передать его в myFunction( Parent& )
,
Ты можешь сделать myFunction(Child(x));
но я думаю что когда попробуешь с голым x
, он пытается построить объект: Parent(x)
и это не удается. Это не то, что вы хотите в любом случае, потому что вы делать хочу экземпляр объекта Child.
Способ, которым make_pair делает нечто подобное, заключается в использовании шаблонного конструктора копирования создаваемого объекта (пары), который создает объект требуемого типа (типов).
Я думаю, что то, что вы хотите сделать, не может быть сделано таким образом, потому что вы хотите создать производный класс, и он не собирается делать это, потому что сигнатура функции Parent&
,
редактировать и альтернативное решение
Я сделал несколько попыток создать решение на основе шаблона, добавив шаблонный конструктор в класс Parent, но это действительно сводится к тому факту, что в конечном итоге вам нужно вызвать конструктор для производного класса.
Я думаю, что единственное разумное решение для этого, чтобы позволить использование myFunction(Parent&)
это использовать метод Indirect, который возвращает ссылку на Parent после создания (временного?) дочернего элемента — это, конечно, означает, что у вас будет много таких методов, если у вас будет много дочерних классов. Я понимаю, что это не так просто, как передать в int (и создать его и передать в ref), но это почти то, что вы хотите 🙂
Других решений пока нет …