C++继承问题,还请各位解答


#include <iostream>
#include <string.h>

using namespace std;

class Person
{
private:
    int m_age;
    char* m_name;

public:
    Person();

    Person(char* name, int age)
    {
        strcpy(this->m_name,name);
        this->m_age = age;
    }

    ~Person();

    void setname(char* name)
    {
        strcpy(this->m_name, name);
    }

    void setage(int age)
    {
        this->m_age = age;
    }

    void getname()
    {
        cout<<"my name is :"<<this->m_name<<endl;
    }

    void getage()
    {
        cout<<"my age is:"<<this->m_age<<endl;
    }
};

class Student:public Person
{
private:
    int m_class;
public:
    Student(char *name , int age , int room):Person(name,age)
    {
        this->m_class = room;
    };

    void setclass(int room)
    {
        this->m_class = room;
    }

    void getclass()
    {
        cout<<"my class is "<<this->m_class<<endl;
    }

    void disp()
    {
        this->getage();
        this->getclass();
        this->getname();
    }
};

int main()
{
    Person *p1 = new Person("som",18);
    p1->getage();
    p1->getname();
    Student *s1 = new Student("abab",20,1);
    s1->disp();

}

输出结果如下,只有p1的输出没有s1的输出

img

    char* m_name;

这是个空指针啊,没崩溃是运气好。

改动的方法很多,只要初始化这个变量就好。最简单的是为修改为定长字符串数组,如

    char m_name[255];

另外,main里new 两个类的时候,用了字面量字符串作为参数,这样最好在相关函数声明中明确为 const,如

   Person(const char* name, int age)
   void setname(const char* name)
   Student(const char *name , int age , int room):Person(name,age)

你的代码根本都不能运行
Person里,你都没有初始化 m_name
上来就 strcpy 了啊

#include <iostream>
#include <string>
 
using namespace std;
 
class Person
{
private:
    int m_age;
    string m_name;
 
public:
    Person() {}
 
    Person(const string& name, int age)
    {
        m_name = name;
        m_age = age;
    }
 
    ~Person() {}
 
    void setname(const string& name)
    {
        m_name = name;
    }
 
    void setage(int age)
    {
        m_age = age;
    }
 
    const string& getname()
    {
        return m_name;
    }
 
    void getage()
    {
        cout << "My age is: " << m_age << endl;
    }
};
 
class Student : public Person
{
private:
    int m_class;
public:
    Student(const string& name, int age, int room) : Person(name, age)
    {
        m_class = room;
    };
 
    void setclass(int room)
    {
        m_class = room;
    }
 
    void getclass()
    {
        cout << "My class is " << m_class << endl;
    }
 
    void disp()
    {
        getage();
        getclass();
        cout << "My name is: " << getname() << endl;
    }
};
 
int main()
{
    Person* p1 = new Person("som", 18);
    p1->getage();
    cout << "My name is: " << p1->getname() << endl;
 
    Student* s1 = new Student("abab", 20, 1);
    s1->disp();
 
    delete p1;
    delete s1;
 
    return 0;
}

img

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 这篇博客: C++——模板编程(P1)中的 函数模板 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:
    template <typename T>
    void print(T t) {
        cout << "call template function" << endl;
    }
    
  • 以下回答来自chatgpt:

    在C++中,当子类继承父类时,如果子类重写了父类的成员函数,并且父类的成员函数是非虚函数,则在通过父类的指针或引用调用成员函数时,实际调用的是父类的成员函数,而不是子类的成员函数。这就是为什么你在代码中通过父类对象和子类对象调用print函数时,只有父类的输出结果可见,而子类的输出结果没有显示出来。

    要解决这个问题,你可以使用虚函数来实现多态性。虚函数是在父类中声明为虚函数,在子类中进行重写的函数。它可以在运行时确定对象的类型,并根据对象的实际类型调用相应的函数。

    以下是你的代码片段的修改,通过将print函数声明为虚函数,可以正确地输出子类对象的结果:

    #include <iostream>
    using namespace std;
    
    class P {
    public:
        virtual void print() {
            cout << "This is P" << endl;
        }
    };
    
    class S : public P {
    public:
        void print() {
            cout << "This is S" << endl;
        }
    };
    
    int main() {
        P p1;
        S s1;
    
        p1.print();
        s1.print();
    
        return 0;
    }
    

    在这个修改后的代码中,print函数在父类P中被声明为虚函数,并在子类S中进行了重写。这样,在通过父类的指针或引用调用print函数时,会根据实际对象的类型进行动态绑定,从而正确地调用子类的print函数。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^