2012-05-15 6 views
2

У меня проблема с назначением указателя времени выполнения на C++. У меня есть класс base с 2-мя членами и потоками.Полиморфизм времени выполнения с указателями в C++

class base { 

    struct base_struct { 
     int a; 
    }; 
    base_struct thread; 
    std::vector<base_struct> threads; 

    void fn() {} 

}; 

derived1 является производным от base и имеет те же два члена (thread и threads), но различного типа.

class derived1 : public base { 
    struct derived_struct11 : public base_struct { 
     int b; 
    }; 
    derived_struct11 thread; 
    std::vector<derived_struct11> threads; 

    void fn() { 
     printf(); 
    } 

}; 

derived2 также получен из base и имеет те же два члена (thread и threads), но различного типа.

class derived2 : public base { 
    struct derived_struct22 : public base_struct { 
     int c; 
    }; 
    derived_struct22 thread; 
    std::vector<derived_struct22> threads; 

    void fn() { 
     printf(); 
    } 

}; 

только во время выполнения я могу знать, следует ли использовать derived1 или derived2. Так что я сделал это следующим образом:

base base_obj; 
derived1 derived1_obj; 
derived2 derived2_obj; 

base *ptr ; 

В функции выполнения:

{ 
    if (condition == yes) 
     ptr = &derived1_obj; 

    else 
     ptr = &derived2_obj; 
} 

Проблема заключается в том, что я могу получить доступ к функциям coreectly с this указателем. Но значение потоков (например:.. threads.size() всегда показано, как из base класса

Я хочу знать, какой лучший способ осуществить это

+2

Это не должно компилироваться, так как 'base :: base_struct' является' private'. –

+0

Это был всего лишь образец :) – deeps8us

+3

Это был плохой пример. Очень важно, чтобы вы отправляли * правильный * код. Это облегчает ** ** облегчение. –

ответ

2

Непосредственная проблема заключается в том, что элементы данных не могут быть виртуальным, поэтому вы не можете переопределить threads в производных классах. Одно из решений может состоять в том, чтобы иметь только один threads в базовом классе и хранить там все экземпляры структур.

Однако вы столкнулись бы с проблемой slicing: вы храните объекты по стоимости с в std::vector<base_struct>. Это означает, что всякий раз, когда вы помещаете в него объект, он будет скопирован в вектор, используя (сгенерированный) экземпляр копии base_struct. Это означает, что производная часть исходного объекта будет срезана, и вы получите только элемент base_struct.

Чтобы включить полиморфизм следует хранить только указатели на base_struct в вашем векторе:

std::vector<base_struct*> threads; 

Другим способом обеспечить виртуальный поглотитель для threads, который затем можно переопределить в производных классов, чтобы вернуть нужную коллекцию , Однако наличие нескольких членов данных с таким же именем в иерархии классов - это ИМО не очень хорошая идея. Это может запутать людей и привести к тонким ошибкам. Поэтому я предпочел бы первое решение, если не будет очень насущной причины сохранять отдельную коллекцию в каждом классе.

+0

Спасибо, ребята .. У меня есть определенная причина сохранять одно и то же имя в обоих классах. Попробуем другие решения. – deeps8us

0

Один из способов будет

base_struct* thread; 
std::vector<base_struct*> threads; // <- hmmmmmmm 

Тогда в ваших производных классов, установить базовые элементы соответствующим образом (а не определение двух новых членов в производном классе - который я думаю, это не то, что вы ищете в любом случае)

 Смежные вопросы

  • Нет связанных вопросов^_^