Я все еще учусь, и у меня есть вопрос, который я надеюсь, что кто-то может помочь мне с:
Можно ли достичь полиморфизма времени компиляции разных классов, наследующих один и тот же базовый класс для использования в массиве?без использования виртуальных функций?
Как любой, кто знает даже небольшой ООП с C ++, если у вас есть что-то вроде
class Base {
public:
virtual void foo (){
std::cout << "I'm the base" << std::endl;
}
}
class A : public Base {
public:
void foo() {
std::cout << "I'm the child" << std::endl;
}
}
class B : public Base {
public:
void foo() {
std::cout << "I'm the child #2" << std::endl;
}
}
//Assume some main here
A *a = new A();
B *b = new B();
Base *someArray[] = {a,b};
someArray[0]->foo(); //"I'm the child"
someArray[1]->foo(); //"I'm the child #2"
Мы знаем, что это работает, потому что функции выполняются, а наследование разрешается во время выполнения.Однако что я должен знать, как это сделать без виртуальных функций или, если возможно, сделать то же самое без использования виртуальных функций?
Предположим, вы делаете что-то вроде этого
class Base {
public:
void foo (){
std::cout << "I'm the base" << std::endl;
}
}
class A : public Base {
public:
void foo() {
std::cout << "I'm the child" << std::endl;
}
}
class B : public Base {
public:
void foo() {
std::cout << "I'm the child #2" << std::endl;
}
}
//Assume some main here
A *a = new A();
B *b = new B();
Base *someArray[] = {a,b};
someArray[0]->foo(); //"I'm the base"
someArray[1]->foo(); //"I'm the base"
ИтакЕсть много вариантов, но я не могу найти то, что будет иметь такое же поведение, как я хочу.Одно из решений, о котором я читал, - создание статического шаблона класса, который работает примерно так:
template <class T>
class Base
{
public:
void interface()
{
// ...
static_cast<T*>(this)->implementation();
// ...
}
static void static_func()
{
// ...
T::static_sub_func();
// ...
}
};
class Derived : Base<Derived>
{
public:
void implementation() {
std::cout << "I am derived" << std::endl;
}
static void static_sub_func();
};
class AlsoDerived : Base<Derived>
{
public:
void implementation() {
std::cout << "I am also derived" << std::endl;
}
static void static_sub_func();
};
//Assume in some main
Derived div;
AlsoDerived alsoDiv;
Derived *someArray[] = { &div, &alsoDiv };//does not work not the same type
Base *someArray[] = { &div, &alsoDiv }; //does not work b/c its a template
Выше приведено не то поведение, которое мне нужно.И затем есть статическое приведение, которое кажется многообещающим, однако мне нужно знать, какой класс это будет в любой момент времени, а это не то поведение, которое я хочу.
class Base {
public:
void foo (){
std::cout << "I'm the base" << std::endl;
}
}
class A : public Base {
public:
void foo() {
std::cout << "I'm the child" << std::endl;
}
}
class B : public Base {
public:
void foo() {
std::cout << "I'm the child #2" << std::endl;
}
}
//Assume some main here
A *a = new A();
A *b = new A();
B *c = new B();
Base *someArray[] = {a,b,c};
someArray[0]->foo(); //"I'm the base"
static_cast<A*>(someArray[1])->foo(); //"I'm the child"
static_cast<B*>(someArray[2])->foo(); //"I'm the child #2"
Это очень близко к тому, что я хочу, однако моя проблема в том, чтобы static_cast работал, мне нужно знать, какой это класс, я хочу использовать static, а не поведение, которое я хочу.
Что ты думаешь?Есть ли лучший способ сделать то, что я хочу?
Спасибо за чтение и, если есть какая-то путаница относительно того, что я спрашиваю, пожалуйста, дайте мне знать, чтобы я мог уточнить.