在下面的代码中,我尝试将 void* 转换为类型的共享指针:
#include <iostream>
#include <memory>
class A
{
public:
A() { l = 0; }
int l;
void Show() { std::cout << l << "\n"; }
};
void PrintA(void *aptr)
{
std::shared_ptr<A> a1;
a1.reset(aptr);
a1->Show();
}
int main()
{
std::shared_ptr<A> a(new A());
PrintA(a.get());
}
Run Code Online (Sandbox Code Playgroud)
但我得到以下编译错误:
$ c++ -std=c++14 try20.cpp
In file included from C:/tools/mingw64/x86_64-w64-mingw32/include/c++/bits/shared_ptr.h:52:0,
from C:/tools/mingw64/x86_64-w64-mingw32/include/c++/memory:82,
from try20.cpp:2:
C:/tools/mingw64/x86_64-w64-mingw32/include/c++/bits/shared_ptr_base.h: In instantiation of 'std::__shared_ptr<_Tp, _Lp>::__shared_ptr(_Tp1*) [with _Tp1 = void; _Tp = A; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]':
C:/tools/mingw64/x86_64-w64-mingw32/include/c++/bits/shared_ptr_base.h:1023:4: required from …Run Code Online (Sandbox Code Playgroud) 我试图在向量中找到weak_ptr。我使用 lambda 表达式作为第三个参数来查找,但我无法理解为什么此代码未编译:
std::vector<std::weak_ptr<Car>> cars;
std::shared_ptr<Car> lambo = std::make_shared<Car>();
std::weak_ptr<Car> wPtr(lambo);
cars.emplace_back(lambo);
const auto pos = std::find(cars.begin(), cars.end(), [&wPtr](const std::weak_ptr<Car>& ptr1) {
return ptr1.lock() == wPtr.lock();
});
if (pos != cars.end())
cout << "Not found!" << endl;
Run Code Online (Sandbox Code Playgroud)
也许有人可以指出我做错了什么。提前致谢。
如果我们有一些智能指针类,它可以接受任意对象并提供引用计数指针,那么我们如何实际存储对引用进行计数的整数?引用计数必须在指向同一对象的智能指针类的所有实例之间共享。
我想到的一种解决方案是将引用计数存储在我们指向的对象中,但这对于一般解决方案来说并不是很好,因为每个对象都必须提供引用计数本身或从提供引用计数的某个对象继承它。
unique_ptr<A>如果对象是匿名传递的(或者根本不传递给任何变量),该对象的行为如何。如何知道 unique_ptr 是否具有来自 c'tor 内部的引用(它被设置到命名变量中)。
基本上,该示例显示直接从返回值对象调用方法 get() 方法。
class A
{
public:
A(int a):_a(a) {}
~A() { std::cout << "d'tor A " << _a << std::endl; }
int _a;
};
std::unique_ptr<A> f1()
{
auto p1 = std::make_unique<A>(1);
return p1;
}
A *f2()
{
A * x = std::make_unique<A>(2).get(); // d'tor called 2
std::cout << x->_a << std::endl; // this will print 2 although destructed.
return x;
}
A *f3()
{
return std::make_unique<A>(3).get(); // d'tor called 3
}
int main(int …Run Code Online (Sandbox Code Playgroud) 这似乎是一个非常愚蠢的问题,所以请耐心等待。我在程序中使用智能指针代替原始指针。建议我不要使用原始指针或尽可能混合两者。我也明白这一点。我也知道只有在必要时才应使用指针。
class Foo{
private: int val;
public:
Foo(int v) :val(v){}
int getvalue() const { return val; }
};
std::shared_ptr<Foo> foo = std::make_shared(Foo(10));
int v;
//Option I
v=foo->getvalue();
//Option II
v=foo.get()->getvalue();
Run Code Online (Sandbox Code Playgroud)
我觉得选项 I 更正确,因为选项 II 使用原始指针。但是使用原始指针在这里可能不会造成伤害,因为我没有分配或取消分配。
我经常对这两个选项感到困惑。哪一个更可取?它们只是一样吗?谢谢。
如何更改下面的代码以使用 unique_ptr 而不是传统指针?
// vector::data
#include <iostream>
#include <vector>
int main ()
{
std::vector<int> myvector (5);
int* p = myvector.data();
*p = 10;
++p;
*p = 20;
p[2] = 100;
std::cout << "myvector contains:";
for (unsigned i=0; i<myvector.size(); ++i)
std::cout << ' ' << myvector[i];
std::cout << '\n';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我尝试了下面的代码,但我遇到了 E0349 没有运算符“++”与这些操作数匹配
unique_ptr<int> p {myvector.data()};
*p = 10;
++p; // <<< ERROR HERE >>>
Run Code Online (Sandbox Code Playgroud) 我有以下代码:
\nstd::unique_ptr<T> first = Get();\n\xe2\x80\xa6\nT* ptr_to_class_member = GetPtr(obj);\n*ptr_to_class_member = std::move(*first.release());\nRun Code Online (Sandbox Code Playgroud)\n这是否会按预期运行,没有副本、1 次移动并且没有内存泄漏?
\n我对 C++ 和智能指针很陌生,尤其是 unique_ptr 的行为。下面是我正在试验的一段代码:
unique_ptr<int> u1 = make_unique<int>(2);
unique_ptr<int> u2 = make_unique<int>();
u2.reset(u1.get());
Run Code Online (Sandbox Code Playgroud)
根据定义,unique_ptr 是一种智能指针,它不与其他智能指针共享它所指向的对象的所有权。但是,为什么上面的代码没有返回错误呢?事实上,如果我尝试打印 u1 和 u2 的值,结果它们确实指向相同的内存地址:
cout<<u1.get()<<endl;
cout<<u2.get()<<endl;
Run Code Online (Sandbox Code Playgroud)
在控制台上显示这些:
0x55800839ceb0
0x55800839ceb0
free(): double free detected in tcache 2 // finally the error appears at the end of the program's execution
Run Code Online (Sandbox Code Playgroud)
但如果我说:
cout<<(*u1)<<endl;
(*u1)=5;
cout<<(*u2)<<endl;
Run Code Online (Sandbox Code Playgroud)
更改不会影响 (*u2),就好像它们位于不同的内存地址中一样。
任何帮助,将不胜感激!感谢您的时间!
我知道这听起来像是一个奇怪的问题,但我很好奇。unique_ptr运算符=将右值引用作为参数并调用reset(r.release()),然后移动自定义删除器。最后,运算符返回*this。喜欢:
// this is pseudo code
unique_ptr& operator=(unique_ptr&& r)
{
reset(r.release()); // Change managed pointer
setDeleter(r.getDeleter());
return *this;
}
Run Code Online (Sandbox Code Playgroud)
unique_ptr重置函数以左值原始指针作为参数,并在更改其管理的指针后删除旧指针。在两者之间,它们具有相同的更改所管理的指针的行为。该行为由相同的 reset() 函数处理。这两个函数做类似的事情,除了参数的差异之外,我想不出一个单独的用例,所以我想知道是否可以重载它们。喜欢:
// this is pseudo code
unique_ptr& operator=(unique_ptr&& r) // or a function named reset
{
changeManagedPtr(r.release()); // and delete old pointer
setDeleter(r.getDeleter());
return *this;
}
unique_ptr& operator=(pointer p) // or a function named reset
{
changeManagedPtr(p); // and delete old pointer
// setDeleter(r.getDeleter()); there is no deleter in p
return *this;
}
Run Code Online (Sandbox Code Playgroud)
为什么这两个函数要分开编写而不是作为同名的重载函数呢?如果可能的话,是不是可以使用像这样不那么混乱的东西:
unique_ptr<int> uniqPtrInt, dest;
int* rawPtrInt …Run Code Online (Sandbox Code Playgroud) 通常,当强引用计数和弱引用计数都达到 0 时,智能指针(强指针或弱指针)将释放控制块。
我在弄清楚如何在以下场景中实现这一点时遇到问题:线程 A 持有强引用,线程 B 持有弱引用,两者都指向同一个块。
假设强引用正在被销毁,并且强引用计数已达到0,则引用析构函数将调用托管对象的析构函数。到目前为止,一切都很好。
但随后它会检查弱引用计数并根据该值决定释放该块。
在这里,我仍然看到线程 B 中的弱引用和线程 A 中的强引用之间可能存在竞争,从而两次释放该块。弱引用可能会自动将其弱引用计数减少到 0,但我不明白为什么强引用在弱引用释放并再次释放之前无法看到这个 0。