c ++重载new [],获取请求对象的数量

时间:2014-04-25 13:43:33

标签: c++ overloading

我想重载operator new []以获取要创建的对象数。 最好的解决方案是以一种方式重载new [],使用new []创建对象时不需要调用者编写任何额外的代码。 即使用简单:

Myclass objectsArray = new Myclass[5];

示例重载:

class Myclass
{
 ...
public:
void* operator new[](size_t size)
{
   int numberOfObjects = figure out how to get number of objects to be created by this call to new[]
   std::cout << "requesting: " << numberOfObjects << " objects" << std::endl;
   void * temp = malloc(size) ;  
   return temp ; 
}
...
}

以下示例程序:

Myclass objectsArray = new Myclass[4];

会输出:

requesting: 4 objects

编辑: 我想在MyClass中做这个,而不是全局

编辑: 我是使用GCC版本4.8.1的Lubuntu 12.0

编辑:问题的目的:

我使用的是自定义内存池分配器,无法开箱即用。所以我需要知道请求了多少个对象,并使用带有池分配器的循环逐个创建它们。

1 个答案:

答案 0 :(得分:1)

您需要定义特定于类的operator new。这对我有用,但要注意count/sizeof(MyClass)表达式中的对齐,派生类大小和分配开销问题:

#include <iostream>
#include <memory>
#include <new>

struct MyClass {
    int dummy[8];
    void *operator new[](std::size_t count) {
        std::cout << "allocating " << count << " bytes, " << ((count-sizeof(void*))/sizeof(MyClass)) << " items\n";
        return ::operator new[](count);
    }
};

int main() {
  auto x = std::make_unique<MyClass[]>(10);
}

(prints:allocating 10 items)我认为可以通过以下方式确定编译器/ stdlib组合的确切开销:

#include <iostream>
#include <memory>
#include <new>

struct MyClass {
  char c;
  char d;
    virtual ~MyClass() {} // needed for introducing overhead
    void *operator new[](std::size_t count) {
        void *p = ::operator new[](count);
        std::cout << "allocating " << count << " bytes\n";
        return p;
    }
};

int main() {
  for( auto count : { 1, 5, 10, 20 } ) {
    std::cout << "allocating " << sizeof(MyClass) << " * " << count << " items\n";
    auto x = new MyClass[count];
    delete[] x;
  }
}

这将在我的机器上(和Coliru上)打印:

分配16 * 1项 分配24个字节,1个项目 分配16 * 5项 分配88个字节,5个项目 分配16 * 10项 分配168个字节,10个项目 分配16 * 20项 分配328个字节,20个项目

所以,我们的count/sizeof(MyClass)(这里)应该是

(count-sizeof(void*))/sizeof(MyClass)

但YMMV等

最后编辑(我希望)

我在64位linux(clang-3.4,clang-3.5&amp; gcc-4.8,libstdc ++&amp; libc ++)上取得了成功,并具有以下how_many_elements函数:

template<class T>
    std::size_t how_many_elements(std::size_t bytes) {
  return (bytes -
    ((!std::is_trivially_destructible<T>::value)*sizeof(void*))
    ) / sizeof(T);
}

所以你的operator new会变成:

void *operator new[](std::size_t count) {
    std::cout << "allocating " << count << " bytes, " << how_many_elements<MyClass>(count) << " items\n";
    return ::operator new[](count);
}

但我没有在32位环境中测试它,YMMV仍然适用。并且请记住复制operator new 每个派生类MyClass,明显将MyClass替换为MyDerivedClass或其他......