创建一个新对象会破坏C ++中具有不同名称的旧对象

时间:2010-05-17 18:07:11

标签: c++ visual-c++ pointers object

这里的第一个问题!

所以,我在使用Visual C ++ 2008中的指针时遇到了一些问题。我正在编写一个程序,它将控制六个摄像头并对它们进行一些处理,以便清理我创建了一个Camera Manager类。该类处理将在所有摄像机上执行的所有操作。下面是一个Camera类,它与每个单独的相机驱动程序进行交互并进行一些基本的图像处理。

现在,我们的想法是,当管理器初始化时,它会创建两个摄像头并将它们添加到矢量中,以便我以后可以访问它们。这里的问题是,当我创建第二台摄像机(camera2)时,出于某种原因调用第一台摄像机的析构函数,然后断开摄像机的连接。

通常情况下,我认为问题出在Camera类的某个地方,但在这种情况下,只要我不创建camera2对象,一切都会完美。

出了什么问题?

CameraManager.h:

#include "stdafx.h"

#include <vector>
#include "Camera.h"

class CameraManager{

    std::vector<Camera>     cameras;

public:

    CameraManager();
    ~CameraManager();

    void CaptureAll();
    void ShowAll();

};

CameraManager.cpp:

#include "stdafx.h"

#include "CameraManager.h"


CameraManager::CameraManager()
{

    printf("Camera Manager: Initializing\n");
    [...]
    Camera *camera1 = new Camera(NodeInfo,1, -44,0,0);
    cameras.push_back(*camera1);

    // Adding the following two lines causes camera1's destructor to be called. Why?
    Camera *camera2 = new Camera(NodeInfo,0,  44,0,0);
    cameras.push_back(*camera2);

    printf("Camera Manager: Ready\n");

}

Camera.h

#include "stdafx.h"

// OpenCV
#include <cv.h>
#include <highgui.h>

// cvBlob
#include "cvblob.h"

// FirePackage
#include <fgcamera.h>

using namespace cvb;

class Camera{

public:

    int cameraID;

    double x, y,z, FOVx, FOVy;

    IplImage *image, *backgroundImage, *labeledImage; 

    CvBlobs   blobs;

    Camera(FGNODEINFO NodeInfo[], int camID, float xin, float yin, float zin);

    ~Camera();

    void QueryFrame();

    void ProcessFrame();

    void GrabBackground();

    void LoadCalibration();

    void Show();

private:

    // ======= FirePackage  ======
    CFGCamera  FGCamera;
    UINT32     Result;
    FGNODEINFO MyNodeInfo;
    UINT32     NodeCnt;
    FGFRAME    Frame;

    // ======= Camera Configuration  ======
    // Trigger Settings
    UINT32  nOn, nPolarity, nSrc, nMode, nParm, BurstCount, DMAMode;

    // Image Settings
    UINT32  AutoExposure, Shutter, Gain, Brightness, Gamma;

    // Image Format Settings
    UINT32  Format, Mode, Resolution, ColorFormat, FrameRate;

    // Structures
    UINT32  TriggerValue;
    UINT32  FormatValue;
    UINT32  DFormatValue;

    // OpenCV Calibration matrices
    CvMat    *intrinsics, *distortion;  
    IplImage *mapx, *mapy;

    void SetUpFirePackage();

    void SetUpOpenCV();

};

Camera.cpp:

#include "stdafx.h"

#include "Camera.h"



Camera::Camera(FGNODEINFO NodeInfo[], int camID, float xin, float yin, float zin) 
    {

        cameraID = camID;
        x = xin;
        y = yin;
        z = zin;
        FOVx = 42.6;
        FOVy = 32.5;

        MyNodeInfo = NodeInfo[cameraID];

        SetUpFirePackage();
        SetUpOpenCV();

        // Grab the first frame
        printf("Waiting for frame...\n");
        QueryFrame();

    };

//Destructor
Camera::~Camera()
{   

        // Stop the device
        FGCamera.StopDevice();

        // Close capture
        FGCamera.CloseCapture();

        // Disconnect before ExitModule
        FGCamera.Disconnect();

        // Exit module
        FGExitModule();

        cvReleaseImage(&image);
    };
[...]
};

2 个答案:

答案 0 :(得分:8)

您需要弄清楚对象和指向对象的指针之间的区别。

您的CameraManager包含vector Camera,因此您必须在向量展开时复制相机。这意味着将创建副本,并在容器的生命周期中的某些点销毁旧副本。

此调用将参数的副本(camera1指向的摄像机)推送到矢量中。

cameras.push_back(*camera1);

当第二个Camera被推入向量时,Camera指向的camera1不是被销毁的,而是被推入的Camera的副本vector。作为旁注,您有一个内存(和对象)泄漏,因为camera1指向您使用new动态分配但不是delete的对象。

听起来好像你没有准备好复制Camera个对象。可能你最好使用一个指针容器(或智能指针来帮助清理释放),或者你可以改变你的Camera类的工作方式来正确应对被复制。没有看到Camera类,很难知道哪个更合适。

答案 1 :(得分:1)

您将原始指针存储在Camera类中,但未定义复制构造函数或赋值运算符(std::vector要求上述内容正常工作)。因此,您可以获得编译器生成的版本,这些版本可以执行浅层复制。

作为cameras.push_back(*camera1);的结果,您实际上创建了一个在push_back返回后被销毁的临时文件。这个临时的析构函数将释放你在语句Camera *camera1 = new Camera(NodeInfo,1, -44,0,0);中分配的资源,向量中的实例将指向不再有效的资源。

您需要不将Camera值存储在向量中(使用某种类型的共享指针)并明确将该类型标记为noncopyable / assignable,否则您应该提供必要的复制/赋值语义。

另外,更不用说你泄漏了camera1camera2