我对我的 new 宏有一个#define,以使用我自己的分配器,例如 MYNEW(Type, Allocator) 我将在其中分配一些原始内存使用 malloc,然后使用 placement new 在原始内存上分配类型,例如
#define MYNEW(Type, Allocator) Allocator->Alloc<Type>(sizeof(Type));`
template<typename Type>
Type* Alloc(unsigned int size) // Allocator::Alloc<Type>
{
return (Type*)new(malloc(reportedSize)) Type;
}
但是,当 Type 没有默认构造函数时,我遇到了问题。我尝试过的一种情况是执行诸如 MYNEW_1(Type, Allocator, ConVar1) 之类的操作,其中 ConVar1 将被传递,例如
#define MYNEW_1(Type, Allocator, ConVar1) Allocator->Alloc<Type>(sizeof(Type), ConVar1);`
template<typename Type, typename ConVarType>
Type* Alloc(unsigned int size, ConVarType Convar1) // Allocator::Alloc<Type>
{
return (Type*)new(malloc(reportedSize)) Type(Convar1);
}
这种方法的问题在于,对于我的自定义 Vector,我还使用 MYNEW 来分配内存。但是,对于用于我的 Vector 的某些 Type,没有默认构造函数,而且我不知道构造函数可能需要多少变量。
有没有人知道如何解决这个问题? (当然不用说使用 std::类型而不是我自己的类型。我这样做是为了了解更多信息)。我不希望只是重载 operator new 因为我在那里有内存跟踪,因为我不希望内存被跟踪两次(Alloc 有更多的内部跟踪,但我展示的是简化的示例)并且宁愿只使用 malloc。
最佳答案
看起来您不仅在做自己的自定义分配器,而且您也不一定要尝试定义与 STL 兼容的分配器。然而,我认为认识到 STL 分配器的所有缺点是有用的,它们是为处理这种情况而设计的。 Allocation与 construction 分开:
Notice that [
allocator::construct] does not allocate space for the element, it should already be available atp(see memberallocateto allocate space).It is equivalent to [call to placement
newthat copies an existing object].
一般来说,我相信您有两个选择:(1) 重载 operator new 来处理内存分配并让系统处理构造,或者 (2) 让您的分配器接口(interface)更像STL 分配器接口(interface)。
“重载 operator new”通常用于表示两件事:(1) 替换它,或 (2) 添加 new 的新版本。当我最初回答时,我使用的是第一个意思(实际上应该称为“替换operator new”或“覆盖operator new”);但仔细考虑一下,我确定真正重载 operator new 会满足您的要求。
我应该提一下,调用重载的operator delete 的语法非常糟糕,许多人仅仅因为这个原因就避免使用这种技术。您可以创建一个函数(例如,deallocate)并使用它,而不是重载 delete。
这种方法的值(value)在于,您遵循将内存分配与对象构造分开的语言标准,而让编译器为您处理对象构造。您不必担心转发运算符,或没有默认构造函数的类,或任何这些问题。
重载operator new/operator delete(当然,我要靠你来充实track和release):
#include <new>
#include <cstdlib>
struct Allocator {
void track(void* p, const void* container) const;
void release(void* p, const void* container) const;
};
void* operator new (size_t size, const Allocator& alloc, const void* container)
{
void* allocated_memory = std::malloc(size);
if (!allocated_memory) {
throw std::bad_alloc();
}
alloc.track(allocated_memory, container);
return allocated_memory;
}
void operator delete(void* p, const Allocator& alloc, const void* container)
{
alloc.release(p, container);
std::free(p);
}
int main()
{
Allocator alloc;
int* i = new (alloc, NULL) int;
operator delete(i, alloc, NULL);
}
重载 operator new 并使用函数 deallocate:
#include <new>
#include <cstdlib>
struct Allocator {
void track(void* p, const void* container) const;
void release(void* p, const void* container) const;
};
void* operator new (size_t size, const Allocator& alloc, const void* container)
{
void* allocated_memory = std::malloc(size);
if (!allocated_memory) {
throw std::bad_alloc();
}
alloc.track(allocated_memory, container);
return allocated_memory;
}
template<typename T> void deallocate(T* p, const Allocator& alloc, const void* container)
{
p->~T();
alloc.release(p, container);
std::free(p);
}
int main()
{
Allocator alloc;
int* i = new (alloc, NULL) int;
deallocate(i, alloc, NULL);
}
您应该考虑的一种情况是当new 成功但构造对象失败时该怎么办。也就是说,当有足够的内存,但由于某些其他原因无法创建对象时。系统实际上足够聪明,可以调用正确的delete(嗯,具有系统认为应该具有的签名的delete)来释放分配的内存;但前提是存在带有该签名的 delete。您可能希望重载operator delete 并提供一个deallocate 函数,其中一个是根据另一个定义的:
void operator delete(void* p, const Allocator& alloc, const void* container)
{
alloc.release(p, container);
std::free(p);
}
template<typename T> void deallocate(T* p, const Allocator& alloc, const void* container)
{
p->~T();
operator delete(p, alloc, container);
}
关于c++ - 处理自定义分配器中没有默认构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10338466/
我正在尝试设置一个puppet节点,但rubygems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由rubygems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
我好像记得Lua有类似Ruby的method_missing的东西。还是我记错了? 最佳答案 表的metatable的__index和__newindex可以用于与Ruby的method_missing相同的效果。 关于ruby-难道Lua没有和Ruby的method_missing相媲美的东西吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7732154/
我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer
我有一个奇怪的问题:我在rvm上安装了rubyonrails。一切正常,我可以创建项目。但是在我输入“railsnew”时重新启动后,我有“程序'rails'当前未安装。”。SystemUbuntu12.04ruby-v"1.9.3p194"gemlistactionmailer(3.2.5)actionpack(3.2.5)activemodel(3.2.5)activerecord(3.2.5)activeresource(3.2.5)activesupport(3.2.5)arel(3.0.2)builder(3.0.0)bundler(1.1.4)coffee-rails(
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
通过rubykoans.com,我在about_array_assignment.rb中遇到了这两段代码你怎么知道第一个是非并行赋值,第二个是一个变量的并行赋值?在我看来,除了命名差异之外,代码几乎完全相同。4deftest_non_parallel_assignment5names=["John","Smith"]6assert_equal["John","Smith"],names7end45deftest_parallel_assignment_with_one_variable46first_name,=["John","Smith"]47assert_equal'John
我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢
我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby1.9+ 关于ruby-主要:Objectwhenrun
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re