使用指针或不将其用于类引用。有什么区别?
Using pointers or not using them for class references. What's the difference?
我有返回对象的函数,但我感到困惑的是,我应该返回对象本身还是指向对象的指针?
这是我的函数的示例:
CImage CDocument::AddImage(string Name, string fileName)
{
CImage img = CImage();
img.Name = Name;
img.Path = fileName;
img.IwImage = Iw2DCreateImage(&fileName[0]);
Images.push_back(&img);
return img;
}
这是正确的还是我应该返回指向对象的指针:
CImage * CDocument::AddImage(string Name, string fileName)
{
CImage * img = new CImage();
img->Name = Name;
img->Path = fileName;
img->IwImage = Iw2DCreateImage(&fileName[0]);
Images.push_back(img);
return img;
}
虽然最后一个代码无法正确编译,因为我收到此错误:
error C2440: 'initializing' : cannot convert from 'CImage' to 'CImage *'
我认为这可能是一个非常简单的问题。我对 c++ 很陌生,所以请耐心等待。
此代码中存在多个问题,在C++中编码时要了解的基本区别在于堆栈分配和堆分配之间。执行此操作CImage img = CImage();
将在堆栈上创建对象。当函数结束时,将自动销毁此对象。现在,如果返回指向此对象的指针,则调用方将获得指向无效内存位置的指针,因为该对象已被销毁。您还将此对象的地址推送到向量中,一旦函数结束,该地址将再次无效。fileName
也存在同样的问题。
要解决此问题,您需要从堆中分配内存,以便在函数结束时不会销毁该对象。您可以使用 C++ 中的 new
在堆上分配对象。所以你的代码会变得CImage* pImage = new CImage();
.请注意,在这种情况下,您有责任使用 delete
释放内存。因此,您可以使用此技术更改函数以返回CImage*
。您也可以将此指针推入矢量Images
。请注意,要释放分配给CImage
的内存,您需要遍历Images
向量并在每个指针上显式调用 delete
。
更好的方法是使用智能指针,例如在这种情况下的std::shared_ptr
,它将自动为您管理delete
的调用。
首先修复指针部分:
CImage * img = new CImage();
修复编译器错误。
考虑一下实例生命周期。一个类的实例一旦到达其作用域的末尾就会被销毁 - 这里是函数的右括号。
第一个示例将在函数结束时销毁(并释放内存)img - 这可能会根据Images.push_back
的实现出现意外行为。
对于返回的实例,如果调用代码如下所示,则很可能会创建变量的副本:
CImage outterImage = myDocument.addImage(...);
outterImage 很可能是 img 的副本,而不是 img 本身。
有关更多详细信息,请查看 C++ 中的实例生命周期。
要初始化新指针,您需要使用 new
关键字。
CImage * img = new CImage();
这会在堆上分配一部分内存(内存的非本地部分),并在那里创建CImage
对象。然后,它获取指向该CImage
对象的指针并将其返回,即使在函数离开其当前范围后,您也可以访问该对象。这是你应该做的。
但是,如果执行CImage img = CImage();
,则可能会发现在代码返回后无法引用CImage
对象。这是因为当您声明一个本地对象(不使用new
)时,它存在于堆栈(内存的另一部分)上,并在函数返回后立即销毁。这意味着即使你有一个指向它的指针,对象也会消失,所以尝试访问它会给你一个段错误。
- 什么时候在C++中返回常量引用是个好主意
- 返回常量对象引用 (getter) 和仅返回字符串有什么区别?
- 在C++17中,引用const字符串的语义应该是什么
- 引用文件的适当方法是什么?
- 引用捕获和在 lambda 中通过引用发送参数有什么区别 (C++)
- C++有什么方法可以在既不调用函数模板也不提供其模板参数的情况下引用函数模板?
- 引用 std::any 或 not_yet_in_std::whatever 的惯用方式是什么?
- 在 Rust 中,指针和引用有什么区别?
- 为什么或在什么情况下,你会将参数作为C++中的引用(或指针)传递给函数?
- 获取通用/前向引用地址有什么意义?
- 返回引用实例和非引用实例(return mystr & vs mystr)之间的区别是什么?
- 删除对象(具有不同类型)的引用时会发生什么情况?
- 对于具有引用返回类型的搜索算法,默认返回值应该是什么?
- 普通的右值引用和 std::forward 返回的引用有什么区别?
- 通过引用函数传递指针参数是什么意思?
- C++ 中的引用范围是什么?
- 将引用绑定到指针的语法是什么?(各种)
- constexpr引用有什么用吗
- 对struct::struct的未定义引用是什么意思
- 什么是常量指针常量引用类型的参数?(const X* const & p)