问题描述
我在以下简单代码中遇到了意外输出的问题。输出在基类上工作正常,但由于某种原因,我在派生类上遇到了麻烦。
#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语句后面的语句没有作用。
此外,您的代码也有缺点。例如,复制赋值运算符会产生内存泄漏。
或者您需要明确定义类汽车的析构函数。
请注意,将数据成员 name
和 title
声明为指向 std::string
类型对象的指针是没有意义的。而是声明 std::string
类型的数据成员。