2017-01-03 65 views
0

我在理解C++的一个重要方面时遇到了问题。看下面的例子:使用C++中的继承指针

class human 
{ 
protected: 
    int age; 
public: 
    human(int a){age=a;} 
    void f(){cout<<"\n the age of human ="<<age;} 
}; 

和下面的类从上面的类派生:

class student: public human 
{ 
private: 
    int num; 
public: 
    student(int b, int c):human(b){num=c;} 
    void g(){cout<<"\n the student with age "<<age<<" has " <<num;} 
}; 

现在我想在下面的代码中使用这些类:

int main() 
{ 
    human h1(10); 
    student s1(11,4); 
    human* p=&h1; 
    p->f(); 
    p=&s1; 
    p->g(); 
} 

但编译器给我错误p->g()。 有什么问题?

+1

你正试图从一个父类访问子方法。阅读多态性,类指针兼容性和虚函数。 – 2017-01-03 07:31:24

+0

@RawN我认识他们。事实上,孩子的方法是“无效的f”,我改变了这个看看效果。我们有一个指向子类的指针,为什么它找不到一个名为'g'的方法。 – Alireza

回答

1

您的基类指针仍然指向基类对象human* p=&h1;。尝试是这样的:

#include <iostream> 

class human 
{ 
protected: 
    int age; 
public: 
    human(int a){ age = a; } 
    void f(){ std::cout << "\n the age of human =" << age; } 
    virtual void g(){} 
}; 

// class student code here... 

int main() 
{ 
    human* p = new student(11, 4); 
    p->f(); 
    p->g(); 
    delete p; 
    return 0; 
} 

或改用s1对象,而不是h1

student s1(11, 4); 
human* p = &s1; 
0

函数g()不是类human的接口的一部分。 phuman*。如果你将p上传到student*,它将起作用。

+0

但指针指向学生。 – Alireza

+0

但编译器不知道这一点。它只知道你的指针的声明是人类的,这是重要的,而不是继承,所以为了这个工作,你必须投到'学生' – Bauss

0

编译器不知道你的指针是student,它只能看到声明为human。要解决这个问题,你需要将它转换为学生指针。

((student*)p)->g(); 
0

你可以宣布在人的虚拟克

class human { 
    public: 
     virtual void g() {} 
    ... ... 
}; 
+0

我已经把学生的地址放在p中。为什么它不能访问'g'。我知道在基类中有'g'可以解决这个问题。但为什么会是这种情况? – Alireza

0

在你的例子中main()有两个对象:人类h1和学生s1。

int main() 
{ 
    human h1(10); 
    student s1(11,4); 
    human* p=&h1; 
    p->f(); 
    p=&s1; 
    p->g(); 
} 
从构造

除此之外,父类人的声明只具有函数f()和儿童类的学生,只是增加了一个函数g()。

人类指针只能查找其类中包含的函数。孩子的查询表中的任何信息对父母来说都是未知的,因为人类从未被告知任何关于孩子班级的信息。

将子对象的引用& s1传递给父指针意味着父对象只能查找它已知的函数。这有时称为对象切片。子函数g()在父类中没有地方守护者。但是,孩子的功能在它的查找表中。

换句话说,孩子既知道本身,因为它被声明类学生它的父:公共人力但父类只知道本身,因为它仅仅是宣布“类人”

由于Bauss说,可以“上传”人类指针,但我不会推荐这种风格。它只会混淆实际使用的指针类型。

这是我将重写主要方式:

int main() 
{ 
    human h1(10); 
    human* p=&h1; 
    p->f(); 
    /* prints " the age of human = 10" */ 

    student s1(11,4); 
    student* q=&s1; 
    q->f(); 
    /* prints " the age of human = 11" */ 
    q->g(); 
    /* prints " the student with age 10 has 4" */ 
}