为什么将指针转换为引用在我的访问器 (getter) 中不起作用?
Why converting a pointer into a reference doesn't work in my accessor (getter)?
我最近学会了如何使用这个技巧将指针转换为引用。但是当我在访问器中执行此操作时,它似乎创建了一个未定义的行为,我不明白为什么。
我为什么要这样做
我有一个拥有class Walker
实例的class WalkerOwner
。这个Walker
实例在代码的其他地方是需要的,所以我提供了一个访问器(getter)到类WalkerOwner
,它提供了一个参考。
class WalkerOwner
{
public:
...
Walker& getWalker() {return m_ownedWalker;} ;
private:
Walker m_ownedWalker;
};
后来,我意识到出于某种原因,WalkerOwner
实际上应该在内部管理指向步行者的指针。由于我不想重构代码的其余部分,将每个引用都更改为指针,因此我尝试将指针转换为 getter 中的引用。
显示问题的代码
#include <iostream>
#include <string>
using std::string;
class Walker
{
public:
Walker() : m_travelledDistance(5) {};
~Walker(){};
void swank() { std::cout << "I have walked " << distanceAsString() << "! How good I am!" << std::endl; };
private:
// Calling this function makes the result even more impressive
string distanceAsString() { return std::to_string(m_travelledDistance) + " meters" ; };
int m_travelledDistance;
};
class WalkerOwner
{
public:
WalkerOwner() {m_ownedWalker = new Walker; } ;
~WalkerOwner() { delete m_ownedWalker;};
// I know I should throw an exception if the pointer is not valid.
Walker& getWalker() {return Walker(*m_ownedWalker);} ; //conversion from pointer into reference
private:
Walker* m_ownedWalker;
};
int main(int argc, char *argv[])
{
// -------
// Case 1
// If "main" owns John the walker, everything seems fine.
// -------
Walker* ptrToJohn = new Walker ;
Walker& john = Walker(*ptrToJohn); //conversion from pointer into reference
john.swank();
delete ptrToJohn ;
// -------
// Case 2
// If someone else owns Jack the walker, a disaster occurs.
// -------
WalkerOwner walkerOwner ;
Walker& jack = walkerOwner.getWalker() ;
// (When I put a breakpoint here, my Integrated Devlopment
// Environnment says that walker.m_travelledDistance = 5)
jack.swank();
std::cin.get(); // Press enter to close
return EXIT_SUCCESS;
}
当我运行此代码时,我得到以下输出:
我走了5米!我多好啊!
我走了-858993460米!我多好啊!
有趣的是,断点显示 jack 在调用函数 "swank()" 之前处于预期状态。(哼...也许哗啦让他失去了理智!
无论如何,如果有人能向我解释这种行为,并可以判断是否有可能制作一个执行此转换的安全访问器,我将非常高兴。
通过编写return Walker(*m_ownedWalker);
,您不会从*m_ownedWalker
"转换"为完整的Walker
:您正在使用当前Walker
作为源创建一个新。
简单return *m_ownedWalker;
正如@user2079303指出的那样:因为你要返回一个新的Walker
,然后不把它保存在任何地方(保存引用与保存实际值不同),它会立即被销毁。然后你拒绝了(现在已经死了,无论如何未初始化的)副本——难怪垃圾被打印出来了!
相关文章:
- 我的神经网络不起作用 [XOR 问题]
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- C++为什么尽管我调用了void函数,它却不起作用
- 为什么在保护模式下继承升级不起作用
- 循环在计数器中不起作用
- 在其他文件中创建类时在 c++ 项目中不起作用
- Visual studio代码重构似乎不起作用(例如,重命名符号-f2)
- 为什么二进制搜索在我的测试中不起作用
- 我的代码中有错误吗?使用BGI图形的C++代码对我不起作用
- 为什么 const std::p air<K,V>& 在 std::map 上基于范围的 for 循环不起作用?
- 带有指定长度字符* 参数的 std::regex_search 在 VS2017 中不起作用?
- Bjarne Stroustrup Book - std_lib_facilities.h - 不起作用(未知类型名称)
- 为什么简单的算术减法在"if"条件下不起作用?
- 为什么Stroustup书中的has_f不起作用
- 你能检查一下为什么在这个代码中从链接列表中删除项目不起作用吗
- 嵌套While循环不起作用(C++问题)
- C++Matching Brackets 2解决方案不起作用
- 为什么这段代码不起作用,我该如何解决?
- 为什么将指针转换为引用在我的访问器 (getter) 中不起作用?