上下文:我有一个队列,支持来自两个不同(/或非)线程的单读/单写,为了强制执行此行为,即一次单读/单写,我需要限制拥有的线程数量队列一次为2(作者已经拥有该队列),我当时正在考虑为队列创建一个shared_ptr,并将编译时已知的最大引用计数设置为2。因此我的问题如下。
问题:有没有一种方法可以实现unique_pointer具有编译时已知的最大引用计数的共享指针(可能使用 's)?我的情况是max_ref_count = 2,超过引用计数限制 = 2 应该是编译时错误。
const auto p = std::make_shared<2, double>(2159); //works fine
const auto q = p; // works fine
const auto err1 = p; // does not compile
const auto err2 = q; // does not compile
Run Code Online (Sandbox Code Playgroud) 我想制作一个特殊的版本,shared_ptr在创建或销毁它时执行特定的操作,但是我的计划似乎被实现了shared_ptr析构函数是非虚拟的,这意味着当我覆盖它时,我的指针永远不会被清除当它们的最后一个实例被销毁时.
想到的唯一选择是将这种行为建立在我想用于我的假设习惯的每个类中shared_ptr,这是不可行的(或者在某些情况下可能).
编辑:
我想要这个的原因是因为我想在lua中使用一些类作为userdata对象,并且我希望我使用这种方式的每个对象都有一个独特的fenv表,当所有引用都被清除时对象已被删除.我打算使用指针的地址,因为它们键入一个包含fenv表的表.
让我们说我有一个小部件可以有其他小部件作为孩子.我在Lua中创建了两个小部件,然后将一个小部件设置为另一个小部件,并删除对子小部件的所有lua引用(事实上它是一个用C++处理的子节点).GC现在可以随时运行并移除孩子.我不一定希望孩子运行它的析构函数,所以我想让它成为一个shared_ptr.这样,在Lua清理它之后,C++对象仍然可以使用它.如果我已将值或函数分配给它的fenv,我仍然希望能够访问它们.只有在删除对子窗口小部件的最终引用时,才能完全删除fenv tabled.
今天我一直在使用Boost :: shared_ptr,我有一个问题.
vector<shared_ptr<KlasaA> > vec;
vec.push_back(shared_ptr<KlasaA>(new KlasaB));
vec.push_back(shared_ptr<KlasaA>(new KlasaC));
vec.push_back(shared_ptr<KlasaA>(new KlasaC));
vec.push_back(shared_ptr<KlasaA>(new KlasaA));
for (vector<shared_ptr<KlasaA> >::const_iterator c_it = vec.begin();
c_it != vec.end(); ++c_it)
{
cout << c_it->get()->foo(10) << endl;
}
Run Code Online (Sandbox Code Playgroud)
上面的循环遍历向量并以多态方式调用foo(10).
我的问题是:
能够...
for (vector<shared_ptr<KlasaA> >::const_iterator c_it = vec.begin();
c_it != vec.end(); ++c_it)
Run Code Online (Sandbox Code Playgroud)
和
cout << c_it->get()->foo(10) << endl;
Run Code Online (Sandbox Code Playgroud)
以更简洁的方式表达?提前致谢.
我正在练习使用boost,现在我正在测试boost共享指针.我有一个可以读取文件的Util类.读完文件后,我的"Read"方法返回一个指向文件内容的boost :: shared_ptr.然后我将这个共享指针传递给我的Parser类,它逐行解析字符串.解析完成后,然后在我的Parser类构造函数的末尾(在'}'),我得到一个"运行时错误",它指向一个boost头文件.更具体地说,check_delete.hpp到"删除x"行:
template<class T> inline void checked_delete(T * x) {
// intentionally complex - simplification causes regressions
typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
(void) sizeof(type_must_be_complete);
delete x;
}
Run Code Online (Sandbox Code Playgroud)
简化的代码看起来像这样:
class File {
string _path;
public:
File(string path)
~File()
void Open();
boost::shared_ptr<string> Read();
void Close();
};
class Parse {
public:
Parse(string path) {
File file = File(path);
file.Open();
boost::shared_ptr<string> fileContentPtr = file.Read();
StartParsing(fileContentPtr);
file.Close();
}
~Parse();
StartParsing(boost::shared_ptr<string> fileContentPtr);
};
int main() {
string path = "<some path to my …Run Code Online (Sandbox Code Playgroud) 我只是通过一个项目的大规模重构来添加一个基类来代替现在所谓的基类的派生类(因为我想要这个类的更多"类型").
我的问题是,一些实用程序函数将原始类A的引用作为shared_ptr,因此函数声明如下所示:
void UtilityClass::func(shared_ptr<A> &a);
Run Code Online (Sandbox Code Playgroud)
但是现在我有了新的基类B和A是从B派生的(以及从B派生的新类C)当我尝试传递A或C的实例时,我遇到编译时错误到现在声明的函数:
void UtilityClass::func(shared_ptr<B> &b);
Run Code Online (Sandbox Code Playgroud)
如果我尝试通过:
shared_ptr<A> a;
utilclass.func(a);
Run Code Online (Sandbox Code Playgroud)
我得到一个编译时错误说(释义):
无法将参数1从'std :: shared_ptr <_Ty>'转换为'std :: shared_ptr <_Ty>'
但是我不知道我怎么解决这个问题,func()将A,B或C实例添加到shared_ptr值的std :: vector中.
谢谢你的时间.
编辑:我还有另一个函数,它接受一个引用,以便它可以为它分配一个新的B实例,然后返回它.
我的项目中有这两个函数:
char* V8StringToChar(v8::Handle<v8::String> str);
char* V8StringToChar(v8::Local<v8::Value> val);
Run Code Online (Sandbox Code Playgroud)
我将它们转换为:
template <class T>
class ArrayDeleter {
public:
void operator () (T* d) const
{ delete [] d; }
};
std::shared_ptr<char> V8StringToChar(v8::Handle<v8::String> str);
std::shared_ptr<char> V8StringToChar(v8::Local<v8::Value> val);
Run Code Online (Sandbox Code Playgroud)
与身体一样
std::shared_ptr<char> V8StringToChar(Handle<String> str) {
int len = str->Utf8Length();
char* buf = new char[len + 1];
str->WriteUtf8(buf, len + 1);
return std::shared_ptr<char>(buf, ArrayDeleter<char>());
}
std::shared_ptr<char> V8StringToChar(Local<Value> val) {
return V8StringToChar(val->ToString());
}
Run Code Online (Sandbox Code Playgroud)
并且每次使用它们(&*V8StringToChar(whatever)).
它构建完美.
它导致运行时错误.
有没有可能失败的情况请提供一些好的解决方案?
许多程序员提倡使用make_shared它,因为它减少了键入并减少了编程错误.然而,在某些情况下使用构造函数shared_ptr是不可避免的.其中一种情况是你有一个你想要拥有的现有指针shared_ptr,因为它shared_ptr<Foo>(&existing_ptr)是错误的代码.相反,你必须使用笨重的shared_ptr<Foo>(shared_ptr<Foo>(), p).你不仅要重复自己,还要创建一个临时对象.
int main()
{
using namespace std;
Foo foo;
foo.n = 1;
{
auto ptr = make_shared<Foo>(move(foo));
ptr->n = 42;
cout << ptr->n << " " << foo.n << '\n';
}
{
auto p = &foo;
auto ptr = shared_ptr<Foo>(shared_ptr<Foo>(), p);
ptr->n = 42;
cout << ptr->n << " " << foo.n << '\n';
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Foo::Foo()
Foo::Foo(Foo &&)
42 1
Foo::~Foo()
42 42
Foo::~Foo()
Run Code Online (Sandbox Code Playgroud)
什么是有一个更简洁的方式shared_ptr …
下面的代码成功地向给定端点发送异步消息.
// message is a boost::shared_ptr<std::string>
// open a UDP socket
boost::asio::ip::udp::socket socket(ioService);
socket.open(boost::asio::ip::udp::v4());
// create the remote endpoint
boost::asio::ip::udp::endpoint remoteEndpoint(boost::asio::ip::address_v4::from_string(address), port);
// asynchronously send a datagram to the remote endpoint
socket.async_send_to(boost::asio::buffer(*message),
remoteEndpoint,
boost::bind(&MyClass::handler,
this,
message,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
socket.close();
Run Code Online (Sandbox Code Playgroud)
但是,如果我将类型更改message为a std::shared_ptr<std::string>而不是a boost::shared_ptr<std::string>则调用async_send_to不会编译.
错误是:
boost/boost/bind/bind.hpp:457:9: No matching function for call to object of type 'boost::_mfi::mf3<void, MyClass, const boost::shared_ptr<std::__1::basic_string<char> > &, const boost::system::error_code &, unsigned long>'.
Run Code Online (Sandbox Code Playgroud)
有人可以解释什么是错的吗?可能是因为我正在使用boost :: bind吗?
我有一个函数将shared_ptr返回给const对象.返回由operator new返回的指针构造的shared_ptr,但返回该指针会导致编译错误:
Error 3 error C2664: 'std::shared_ptr<_Ty>::shared_ptr(std::nullptr_t)' : cannot convert parameter 1 from 'script::float_data *' to 'std::nullptr_t' c:\xxx\value.cpp 59
Run Code Online (Sandbox Code Playgroud)
以下是导致错误的代码:
shared_ptr< const data > float_data::operator + ( shared_ptr< const data > rhs ) const
{
int rhs_as_int; float rhs_as_float;
switch( rhs->to_numeric( rhs_as_int, rhs_as_float ) )
{
case E_INT:
return new float_data( val + rhs_as_int );
case E_FLOAT:
return new float_data( val + rhs_as_float );
}
}
Run Code Online (Sandbox Code Playgroud)
这些课程是:
class data
{
public:
enum type
{
E_INT,
E_FLOAT,
E_STRING
};
public:
virtual …Run Code Online (Sandbox Code Playgroud) 我正在初始化一个shared_ptr以映射到一个名为GetData的单独函数中.此映射作为参数传递给GetData函数.但是,在main中,map在调用GetData函数后返回空.
#include <memory>
#include <map>
void GetData(std::shared_ptr<std::map<int, int>> data);
int main()
{
std::shared_ptr<std::map<int, int>> data2 = std::make_shared<std::map<int, int>>();
GetData(data2);
return 0;
}
void GetData(std::shared_ptr<std::map<int, int>> data)
{
data = std::make_shared<std::map<int, int>>
(std::initializer_list<std::map<int, int>::value_type>{
{ 1, 2 },
{ 5, 6 },
{ 4, 5 }
});
}
Run Code Online (Sandbox Code Playgroud)
我在这做错了什么?
更新: 如果在参数仍未通过引用传递的情况下重写方法如下,我确实在调用GetData方法后在main中填充了map.
void GetData(std::shared_ptr<std::map<int, int>> data)
{
data->insert(std::pair<int, int>(1,2));
data->insert(std::pair<int, int>(45, 2));
}
Run Code Online (Sandbox Code Playgroud) c++ ×10
shared-ptr ×10
boost ×2
c++11 ×2
boost-asio ×1
boost-bind ×1
c++14 ×1
constructor ×1
inheritance ×1
memory ×1
return ×1
stdmap ×1
unique-ptr ×1
visual-c++ ×1