出乎意料的虚函数返回字符串

问题描述

我在以下简单代码中遇到了意外输出的问题。输出在基类上工作正常,但由于某种原因,我在派生类上遇到了麻烦。

#include <iostream>
#include <string>
using namespace std;


class vehicle {
public:
    string* name;
    vehicle() {}
    vehicle(const string& inputName) {name = new string(inputName);} //constructor
    virtual ~vehicle() {delete name; name = nullptr;} // always make base class destructor virtual
    //vehicle(const vehicle& rhs) {*this = rhs; cout << "copy called" << endl;} //copy constructor
    vehicle& operator=(const vehicle& rhs) {
        cout << "assignment called" << endl;
        if(this == &rhs){
            return *this;
        }
        name = new string(*rhs.name);
        return *this;
    } //assignment operator
    virtual string& getName() const {return *name; cout << "base" << endl;} //mark function const if we are not going to make any changes to the object
};

class car : public vehicle {
    string *title = new string;
public:
    car() : vehicle() {}
    car(const string& inputName) : vehicle(inputName) {*title = inputName;}
    virtual ~car() {}
    virtual string& getName() const {string temp = *title; return temp; cout << "derived" << endl;}
};
int main() {

    car test("honda");
    string temp;
    temp = test.getName();
    cout << temp;

    return 0;
}

我打算获得以下输出

honda

但我得到:

~weird square Boxes~

编辑:

我真正想要完成的是派生类中的以下内容

virtual string& getName() const {return "Car: " + *name;} 

在我因使用堆作为字符串而感到愤怒之前,请知道我只是在这里进行试验。我的理解是,这在理论上应该可行。

解决方法

这个功能

virtual string& getName() const {string temp = *title; return temp; cout << "derived" << endl;}

调用未定义的行为,因为它返回对本地对象 temp 的引用,该对象在退出函数后将不存在。

你可以像这样定义函数

virtual const string& getName() const {return *name;}

const string& getName() const override { return *title;}

并且return语句后面的语句没有作用。

此外,您的代码也有缺点。例如,复制赋值运算符会产生内存泄漏。

或者您需要明确定义类汽车的析构函数。

请注意,将数据成员 nametitle 声明为指向 std::string 类型对象的指针是没有意义的。而是声明 std::string 类型的数据成员。