繁体   English   中英

使用指针或不使用指针作为类引用。 有什么不同?

[英]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 )时,该局部对象存在于堆栈(内存的另一部分)中,并在函数返回时立即销毁。 这意味着即使您有一个指向它的指针,该对象也将消失,因此尝试访问它会给您一个段错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM