我在C ++中有一些继承困难。假设我有一个基类Parent:
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库存2种类型的对象:数字或符号。所以我创建了一个父对象的向量。
问题是:我想得到两个向量的交叉点ParentVector。
我可以在向量vtParent中添加一个对象Numeric或Symbolic但是我不能调用方法Intersection对应每种类型的对象。它总是调用类Parent的方法交集。
任何人都有一些想法或建议?非常感谢。
//编辑:我忘记了ParentVector类也是Parent类的子类。
//更新:感谢您提供的所有有用帮助。现在,我想执行下面的代码来计算两个向量的交集:Parent:
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);
}
}
我没有编写函数代码&#39;虚拟Parent * Parent :: Intersection(Parent anotherParent)&#39;,所以我无法执行上面的代码。有人知道如何解决这个问题吗?
//这里的想法是我想调用函数&#39; Numeric * Intersection(Numeric anotherNumeric)&#39;或者&#39; Symbolic * Intersection(Symbolic anotherSymbolic)&#39;
//完成,感谢你的所有建议。
答案 0 :(得分:4)
您的子类正在更改Intersection
函数的返回类型和参数类型,这实际上使它成为一个新函数而不是多态行为。这些函数必须具有相同的函数签名。
答案 1 :(得分: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
}
答案 2 :(得分:0)
如果您不使用C ++ 11,则当您将push_back
符号或数字对象放入向量时,您将面临对象切片。在C ++ 11的情况下,如果您的类定义适合它,系统将使用移动语义来填充向量,您应该定义移动构造函数和移动赋值运算符,或者取决于这些函数的默认值。
要克服对象切片,可以使用
std::vector<Parent*> vtParent;
代替使用std::vector<Parent> vtParent;
虚拟函数应保持与Ami Tavory和Adam Finley所观察到的相同的函数返回。但在你的情况下,你可以使用如下,因为你的返回类型是协变的。
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;
}
答案 3 :(得分: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;
}