如何创建一个不指向原始对象但指向对象副本的智能指针?
std::unique_ptr<cv::Mat> mat_p;
if(isChangePersistent){
// Use a pointer on the original object
mat_p = std::make_unique<cv::Mat>(&_img);
}else{
// Use a pointer on a copy of the original object
mat_p = std::make_unique<cv::Mat>(&(_img.clone()));
}
我们的想法是只使用指针mat_p
在代码中进一步工作。这样,如果我必须处理原件或副本,我不必再检查,因为指针始终指向正确的对象。
编译此代码会引发错误error: taking address of temporary [-fpermissive]
。只有第二个std::make_unique
会抛出此错误。 _img
是定义此方法的类的成员变量。
我有点理解,因为我给智能指针一个临时对象的地址。这样做的正确方法是什么?使用new
创建对象并将该创建的指针指向智能指针的构造函数?
我使用shared_ptr
更新了我的代码,我尝试在else块中分配对象,以便用临时地址摆脱错误:
std::shared_ptr<cv::Mat> mat_p;
if (isChangePersistent) {
// Use a pointer on the original object
mat_p = std::make_shared<cv::Mat>(&_img);
} else {
// Use a pointer on a copy of the original object
cv::Mat* img_tmp = new cv::Mat();
*img_tmp = _img.clone();
mat_p = std::make_shared<cv::Mat>(img_tmp);
}
现在我收到此错误,已经是第一个std::make_shared
:
error: no matching function for call to ‘cv::Mat::Mat(cv::Mat*)’
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
我不再理解这个问题了。
答案 0 :(得分:2)
cv::Mat
已经是引用计数对象。它基本上就像shared_ptr<>
你真的不需要在外部shared_ptr<>
,unique_ptr<>
或任何其他额外的智能指针包装器中保存它。
按原样使用。
如果您有cv::Mat img1, img2
则:
img2 = img1;
将使两个变量共享相同的图像(更改一个将更改另一个)。 img2 = im1.clone();
会为img2
提供img1
。答案 1 :(得分:1)
如果由于某种原因必须使用exec
,那么您应该使用课程copy constructor。否则,#include<stdio.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<unistd.h>
int main(int argc, char *argv[])
{
int args = argc-1;
pid_t childpid = fork();
// error
if (childpid < 0)
{
perror("fork() error");
exit(-1);
}
// parent process
if (childpid != 0)
{
printf("Parent Process started, now waiting for ID: %d\n", childpid);
wait(NULL);
printf("Parent Process resumeed. Child exit code 0. Now terminating\n");
exit(0);
}
// child process
if (args > 0)
{
printf("Child process has begun. %d argument/s provided\n", args);
int i;
for (i = 1; i <= argc; i++)
{
execlp(argv[i], argv[i], NULL);
}
execvp(argv[1], argv);
}
else
{
printf("No arguments provided, terminating child\n");
}
return 0;
}
也会起作用。
unique_ptr
您收到错误shared_ptr
,因为#include <memory>
#include <iostream>
struct A
{
int n;
A(int n = 1) : n(n) { }
A(const A& a) : n(a.n) { } // copy constructor
};
int main()
{
A *a1 = new A(1);
std::unique_ptr<A> aptr(a1);
std::unique_ptr<A> bptr(new A(*a1)); // Copy the object a1 points to
}
的构造函数没有采用error: no matching function for call to ‘cv::Mat::Mat(cv::Mat*)’
类型的重载。但是,您的问题更多的是您尝试复制对象而不是缺少接受Mat
的构造函数。以下是解决错误的方法:
Mat *
如果你创建了cv :: Mat,那么请确保为它定义一个合适的拷贝构造函数,否则Mat *
会抛出你在问题的后面部分中出现的相同错误。
答案 2 :(得分:0)
shared_ptr
类型的对象具有获取所有权的能力 一个指针,并分享所有权:一旦他们取得所有权, 指针的所有者组负责删除它时 最后一个人释放了所有权。
答案 3 :(得分:0)
智能指针std::shared_ptr<cv::Mat> mat_p;
if (isChangePersistent) {
// Use a pointer on the original object
mat_p = std::make_shared<cv::Mat>(&_img);
} else {
// Create a new shared pointer that holds a copy of _img on the heap
mat_p = std::make_shared<cv::Mat>(cv::Mat(_img));
}
和cv::Mat(_img)
都是关于建立对象的生命周期。如果对象的生命周期已在其他地方进行管理,您不想更改对象生命周期的管理方式。
在您的情况下,最简单的解决方案可能是使用 dumb 指针,让生命周期问题完全独立。
std::unique_ptr