2015-06-18 3 views
0

У меня есть трудности с наследованием на C++. Предположу, у меня есть базовый класс Parent:вызов родительского объекта Метод ребенка C++

class Parent{ 
public: 
     ... 
     virtual Parent Intersection(Parent anotherParent); 

} 

и 2 классов дети числовой и символьный с реализацией методы Пересечения:

class Numeric : public Parent{ 
public: 
     ... 
     Numeric Intersection(Numeric anotherNumeric) 
     { 
     ... 
     }; // do intersection with another object numeric 

} 

// class Symbolic 
class Symbolic : public Parent{ 
public: 
     ... 
     symbolic Intersection(Symbolic anotherSymbolic) 
     { 
     ... 
     }; // do intersection with another object symbolic 

} 

и последним классом ParentVector:

class ParentVector : public Parent{ 
public: 
     ... 
     ParentVector Intersection(ParentVector anotherParentVector); 

private: 
     std::vector<Parent> vtParent; // vector stock object Parent (Numeric or Symbolic) 

} 

Я хочу вектор vtParent stock 2 типа объекта: числовой или символический. Поэтому я создал вектор родительских объектов.

Проблема в следующем: я хочу получить пересечение 2 векторов ParentVector.

Я могу добавить объект Числовой или символьный в векторе vtParent, но I не может вызов метода Пересечение соответствует каждому типу объекта. Он всегда вызывает метод Пересечение класса Parent.

У кого-нибудь есть идеи или предложения? Большое спасибо.

// edit: Я забыл, что класс ParentVector также является родительским классом родительского класса.

// ОБНОВЛЕНИЕ: спасибо за все ваши полезные советы. Теперь я хочу, чтобы выполнить код ниже, чтобы вычислить пересечение 2 векторов Родитель:

ParentVector* Intersection(ParentVector anotherParentVector){ 
    ParentVector* result; 
    Parent* tmp; 

    for(int i = 0; i < this->vtParent.size(i); i++){ 
      // PROBLEM with this line because I don't write the code of 
      // function 'virtual Parent* Parent::Intersection(Parent anotherParent)' 

      *tmp = this->vtParent.at(i)->Intersection(anotherParentVector.getParentVector().at(i)); 
      result->getParentVector.push_back(tmp); 
    } 
} 

Я не писать код функции «виртуального Родитель * Родитель :: Пересечения (Parent anotherParent)», так что я не может выполнить указанный выше код. У кого-то есть идея, как решить эту проблему?

// Здесь, идея, я хочу, чтобы вызвать функцию 'Числовых * Пересечение (Числовой anotherNumeric)' или 'Символическое * Пересечение (Символическое anotherSymbolic)'

// FINISH, спасибо за все ваши предложения.

+2

У вас есть виртуальные функции с различными типами возврата. См. [This] (http://stackoverflow.com/questions/4665117/c-virtual-function-return-type). –

ответ

0

Вы сталкиваетесь с объективом, когда push_back объект символьного или числового в вектор, если вы не используете C++ 11. В случае, если система C++ 11 будет использовать перемещение symantic для заполнения вектора, если для него может быть адаптировано определение класса, либо вы должны определить move constrctor и оператор присваивания переадресации, либо в зависимости от настроек этих функций.

Чтобы преодолеть объект нарезку, вы можете использовать

std::vector<Parent*> vtParent; 

вместо использования std::vector<Parent> vtParent;

И виртуальные функции должны иметь одни и те же функции, как возврат наблюдается Ами Tavory и Адам Финли. Но в вашем случае вы можете использовать следующее, так как ваши возвращаемые типы являются ковариантными.

virtual Parent* Intersection(Parent anotherParent); 
symbolic* Intersection(Symbolic anotherSymbolic); 
Numeric* Intersection(Numeric anotherNumeric); 

Обратите внимание, что виртуальный деструктор отсутствует в базовом классе.

Редактировать: Вы можете упростить свой ParentVector::Intersection() следующим образом.

std::vector<Parent*> Intersection(ParentVector anotherParentVector){ 
    std::vector<Parent*> result; 
    Parent * tmp; 
    std::vector<Parent*>::iterator it= vtParent.begin(); 
    for(; it != vtParent.end(); ++it){ 
      tmp= it->Intersection(anotherParentVector.getParentVector().at(i)); 
      result->getParentVector.push_back(tmp); 
    } 
    return result; 
} 
+0

вещь, которую я не понимаю, - «виртуальные функции должны поддерживать ту же функцию». Можете ли вы немного объяснить? – Amateur

+0

@ Amateur Я отредактировал свой ответ с более подробной информацией. – Steephen

+0

спасибо за ваше предложение, можете ли вы просмотреть мое новое обновление? – Amateur

4

Ваши дочерние классы меняют тип возвращаемого значения и тип параметра функции Intersection, что по сути делает его новой функцией, а не той, которая ведет себя полиморфно. Функции должны иметь одну и ту же сигнатуру функции.

+0

вы имеете в виду, что если я изменю возвращаемый тип функции: Числовое пересечение (числовое другое числовое) до родительского пересечения (родительское другоеNumeric) ??? – Amateur

0

Да это оленья кожа вызова удалять на вещи, но только, чтобы показать вам маршрут, который нужно принять

#include <iostream> 
#include <vector> 
#include <memory> 
class Parent{ 
public: 
    virtual Parent* Intersection() = 0; 
}; 

class Numeric : public Parent{ 
public: 
    Parent* Intersection() 
    { 
     std::cout << "\nNumeric!"; 
     return new Numeric; 
    } // do intersection with another object numeric 

}; 

// class Symbolic 
class Symbolic : public Parent{ 
public: 
    Parent* Intersection() 
    { 
     std::cout << "\nSymbolic!"; 
     return new Symbolic; 
    } // do intersection with another object symbolic 

}; 

class ParentVector{ 
public: 
    ParentVector() 
    { 
     vtParent.push_back(std::make_unique<Symbolic>()); 
     vtParent.push_back(std::make_unique<Numeric>()); 
    } 
    void print() 
    { 
     for (const auto& e : vtParent) { 
      e->Intersection(); 
     } 
    } 
    ParentVector Intersection(ParentVector anotherParentVector); 

private: 
    std::vector<std::unique_ptr<Parent>> vtParent; // vector stock object Parent (Numeric or Symbolic) 

}; 


int main() 
{ 
    ParentVector pvec; 
    pvec.print(); 

    std::cout << '\n'; 
    system("PAUSE"); 
    return 0; 
} 
1

3 проблемы в вашем коде:

когда значение магазина в STL контейнер, копия будет вызываться конструктор, объект подкласса будет нарезан. поэтому, если вы хотите сохранить полиморфизм какого-либо объекта, можно использовать указатель/smart_pointer или reference. в сценарии контейнера подходит указатель/smart_pointer.

std::vector<Parent*> vtParent 

тип параметра должен быть идентичным между базовым классом и производным классом.

вопрос типа возвращаемого значения см enter link description here

class Parent{ 

public: 

    ... 
    virtual Parent& Intersection(Parent anotherParent); 

} 


class Symbolic : public Parent{ 
public: 
     ... 
     symbolic& Intersection(Symbolic anotherSymbolic) 
     { 
     ... 
     }; // do intersection with another object symbolic 

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