我在尝试从指向其基类的指针创建类的副本时遇到了一些麻烦。最好通过这个例子来说明:
#include <iostream>
#include <vector>
class Base {
public:
Base() { }
virtual void test() { std::cout << "I am just the base class\n"; }
};
class First : public Base {
public:
First() { }
void test() { std::cout << "This is the First class\n"; }
};
class Second : public Base {
public:
Second() { }
void test() { std::cout << "This is the Second class\n"; }
};
int main() {
First *f = new First();
Second *s = new Second();
// First, I keep a vector of pointers to their base class
std::vector<Base *> ptrs;
ptrs.push_back(f);
ptrs.push_back(s);
ptrs[0]->test(); // Properly calls the implemented virtual class by inheritor
ptrs[1]->test(); // Properly calls the implemented virtual class by inheritor
// Now, I want to *copy* the class without it being spliced to just the base class
// from the ptrs vector (not from 'f')
First *f2 = new First(*ptrs[0]);
}
我最终得到的错误是:
test.cpp: In function ‘int main()’:
test.cpp:35: error: no matching function for call to ‘First::First(Base&)’
test.cpp:12: note: candidates are: First::First()
test.cpp:10: note: First::First(const First&)
有没有办法将此指针转换为复制完整的对象,而不仅仅是基类?或者我是否需要存储指向继承者的指针才能使其工作?
答案 0 :(得分:3)
你可以这样做:
First *f2 = 0;
if ( typeid(*ptrs[0]) == typeid(First))
f2 = new First(*dynamic_cast<First*>(ptrs[0]));
这应该有效。
但更好的方法是在基类中使用clone()
虚函数,并将其实现为派生类:
class Base
{
public:
virtual ~Base() { } //virtual destructed added by me!
virtual Base *clone() = 0;
};
class First : public Base
{
public:
virtual First *clone() { /* implement it */ } //Covariant return type
};
和
First *f2 = 0;
if ( typeid(*ptrs[0]) == typeid(First))
f2 = ptrs[0]->clone(); //no need to use new
需要注意两点:
clone()
的不同返回类型。它被称为covariant return type。答案 1 :(得分:1)
First *fx=(First*)ptrs[0];
First *f2 = new First(*fx);