假设您有基类Unix_tree
,派生Unix_tree_type1
,Unix_tree_type2
等等。为什么我无法将Unix_tree
投射到Unix_tree_type
......?有没有办法进行这样的演员表演?派生类包含抽象方法的实现,其目标是以不同方式打印基类中包含的数据。感谢。
class Unix_tree
{
public:
Unix_tree ()
{
tree_it.tree = &tree;
}
Unix_tree(const Unix_tree& utree) : num_of_files(utree.num_of_files), tree(utree.tree), tree_it(utree.tree_it)
{
tree_it.tree = &tree;
};
int num_of_files;
map<int, pair<int, string> > names;
vector<pair<int, int> > edges;
Tree< pair<int, string> > tree;
TreeIterator< pair<int, string> > tree_it;
string input_format;
string output_format;
static Unix_tree* load_tree(istream& input_info);
void load_names(istream& input_info);
void load_tree_nodes(vector<int>& levels);
Unix_tree* convert(string format);
virtual void load(istream& input_info) = 0;
virtual void print_function(const Tree<pair<int, string> >* node, const vector<bool>& visited ) = 0;
void print_tree();
};
class Unix_tree_type1 : public Unix_tree
{
public:
void load(istream& input_info);
void print_function(const Tree<pair<int, string> >* node, const vector<bool>& visited);
};
答案 0 :(得分:1)
您可以投射指针,所以:
Unix_tree *p = ...;
Unix_tree_type1 *q = (Unix_tree_type1*)p;
但我不认为你想这样做。方法调用会自动执行您想要的操作,因此:
Unix_tree *p = ...; // points to an instance of Unix_tree_type1
p->load(...); // calls Unix_tree_type1::load, not Unix_tree::load
答案 1 :(得分:1)
你可以施放,但你不应该。您应该只调用基类指向的对象的成员函数,并调用您的实现。这就是虚拟成员函数的重点。
答案 2 :(得分:1)
没有办法将基类强制转换为派生类,因为它没有意义。在没有涉及太多OO细节的情况下,从基类继承的目的不仅仅是“打印基类中包含的数据” - 而是提供更具体的功能实现。所以想象一下“Fruit”类,其方法是“GetJuice()”。继承自“Fruit”的类“Apple”可能会继承方法“GetJuice()”。但是,除了该方法之外,它还可以定义其他方法或属性,例如“FindAppleWorm()”,这些方法或属性将特定于其类型。因此,当你有一个Apple类时,可以将它强制转换为类型fruit,并且调用Fruit类的“GetJuice()”方法仍然是有意义的。但是,如果将一个Fruit类转换为Apple类,您可以调用“FindAppleWorm()”方法,但它不会出现。
面向对象语言中的继承概念与多态的概念相辅相成。我建议wikipedia article进行一次很好的介绍。
答案 3 :(得分:0)
为什么你不能?当然,你可以 - 它是有效的上传,可以由dynamic_cast
完成。但你应该投射指针或引用,而不是类型本身。
Unix_tree_type1* ptree1 = ...; // Some pointer initialization
Unix_tree* ptree2 = dynamic_cast<Unix_tree*>(ptree1);// Safe
Unix_tree* ptree3 = static_cast<Unix_tree*>(ptree1); // Also safe