I search a method to overload operator of delete[] or suitable destructor for a code:
#include <iostream>
#include <string>
using namespace std;
class A {
private:
string name;
public:
A(string name){
this->name=name;
};
~A(){
cout<<"Destructor. Destroyed "<<name<<"\n";
};
void operator delete(void* p, A* a){
cout<<"-Delete "<<a->name<<"\n";
};
void operator delete(void* pointer){
cout<<"Delete"<<"\n";
};
void operator delete[](void* pointer){
cout<<"Delete[]"<<"\n";
};
};
int main(){
int number = 5;
A** a = new A* [ number ];
delete [] a;
system("pause");
return 0;
};
But whatever I tried default delete[] is started each time from the file delete2.cpp. What do I do wrong?
[ADDED] Added an attempt to overload delete[].
Your code is not creating or destroy instances of A, only pointers to it.
#include <iostream>
#include <string>
using namespace std;
class A {
private:
string name;
public:
A() {}
A(string name){
this->name=name;
};
~A(){
cout<<"Destructor. Destroyed "<<name<<"\n";
};
void operator delete(void* p, A* a){
cout<<"-Delete "<<a->name<<"\n";
};
void operator delete(void* pointer){
cout<<"Delete"<<"\n";
};
void operator delete[](void* pointer){
cout<<"Delete[]"<<"\n";
};
};
int main(){
int number = 5;
A* a = new A[ number ];
delete [] a;
system("pause");
return 0;
};
Calls operator[] as expected: http://ideone.com/EuS3Hi
Related
Is there a pattern to automatically call a destructor of a placement-new initialized object on the stack when it exits scope? I want to skip the need to memorize to call the destructor explicitly. Or, is there a different method than the placement-new to construct a stack based object with a variable size data[] tail? I use g++.
/* g++ f.cpp -o f.exe */
/* 8< --- f.cpp ---- */
#include <stdio.h>
#include <stdlib.h>
#include <string>
class aclass {
public:
aclass(int size) : size_(size) {};
~aclass() { /* do something */ };
int size_;
char data[0];
};
void f(int size)
{
char v[sizeof(aclass) + size];
aclass *p = new(static_cast<void*>(&v)) aclass(size);
p->~aclass();
}
int main(int argc, char **argv)
{
f(10);
f(100);
return 0;
}
You can create a wrapper class like this:
template <typename T>
class Foo {
private:
T *m_ptr;
public:
Foo(void *area, int size) {
m_ptr = new(area) T(size);
}
Foo(const Foo &) = delete;
~Foo() {
m_ptr->~T();
}
void operator=(const Foo &) = delete;
T *operator->() {
return m_ptr;
}
};
Usage:
void f(int size) {
char v[sizeof(aclass)+size];
Foo<aclass> p(v, size);
p->doSomething(); // call a function from aclass
}
Note that you're using a GCC extension, as size is not a compile-time constant.
If it was a compile-time constant, then you could put v into Foo (and size would be a template parameter), so f would be simpler.
There is already a standard wrapper template class which does this - std::unique_ptr.
Note the caveats in the comments
#include <cstdio>
#include <cstdlib>
#include <string>
#include <memory>
class aclass {
public:
aclass(int size);
~aclass();
int size_;
char data[0]; // this is illegal in standard c++
};
// deleter which only calls destructor, does not deallocate
struct inplace_deleter
{
template<class T>void operator()(T* p) const noexcept
{
p->~T();
}
};
void f(int size)
{
// VLAs are not standard c++. This is a compiler extension on gcc.
char v[sizeof(aclass) + size];
using ptr_type = std::unique_ptr<aclass, inplace_deleter>;
auto p = ptr_type(new(&v) aclass(size));
// auto deleted
}
int main()
{
f(10);
f(100);
return 0;
}
https://godbolt.org/z/qEwld-
I have a simple program where I am trying to do operator overloading for new and delete.
Just for trying, I did operator overloading for new and delete in global scope apart from class scope.
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
void * operator new(size_t size)
{
cout<<"\n\nGlobal scope new:\n";
void * ptr = malloc(size);
return ptr;
}
void operator delete(void *ptr)
{
cout<<"\n\nGlobal scope delete:\n";
free(ptr);
}
class test
{
public:
int age;
string name;
test(string str, int a)
{
age = a;
name = str;
}
void display();
};
void test::display()
{
cout<<"\n\nname is:-"<<name<<" and age is :- "<<age<<endl;
}
int main()
{
test *t = new test("sanjeev",29);
if(t!=NULL)
cout<<"\n\nMemory allocated:"<<endl;
t->display();
delete t;
}
Now on executing this program I am seeing that new is called 3 times and delete is called 3 times.
If I declare new and delete operator overloading inside class only one time call to new and delete is happening.
What is the reason behind this flow?
std::string ultimately uses the global operator new. You're creating two std::strings.
You should override operator new in your base class if you don't want new to be called multiple times in this case:
class CBaseTest
{
public:
void *operator new(const size_t allocation_size)
{
cout<<"\n\nMy new invoked:\n";
return ::malloc(allocation_size);
}
void operator delete(void *block_of_memory)
{
cout<<"\n\nMy delete invoked:\n";
::free(block_of_memory);
}
};
class test : public CBaseTest
{
public:
int age;
string name;
test(string str, int a)
{
age = a;
name = str;
}
void display();
};
void test::display()
{
cout << "\n\nname is:-" << name << " and age is :- " << age << endl;
}
Here
test *t = new test("sanjeev", 29);
will invoke your new method.
Similarly,
delete t;
will invoke your delete method
Now, if you try to allocate memory using new for your class test or any classes derived from CBaseTest then your new will be called.
I'm reading Effective C++ 3rd Edition, item52 "Write placement delete if you write placement new".
I want to how to make the operator delete automatically called after construction throwing an exception.
#include <iostream>
using namespace std;
class A {
int i;
public:
static void* operator new(std::size_t size) throw(std::bad_alloc) {
return malloc(size);
}
static void operator delete(void* p) throw() {
cout << "delete" << endl;
free(p);
}
A() {
throw exception();
}
};
int main() {
A* a = new A;
}
The above codes only output:
terminate called after throwing an instance of 'std::exception'
what(): std::exception
[1] 28476 abort ./test_clion
Reference: operator delete, operator delete[]
I should write new in try {}. Know too little about exceptions for now.
#include <iostream>
using namespace std;
class A {
int i;
public:
static void* operator new(std::size_t size) throw(std::bad_alloc) {
return malloc(size);
}
static void operator delete(void* p) throw() {
cout << "delete" << endl;
free(p);
}
A() {
throw exception();
}
};
int main() {
try {
A* a = new A;
} catch (const exception&) {
}
}
And the output:
delete
I have a class X and method addX() which allocates objects of X on the heap. I want to restrict client-code from directly allocating objects of X (so that the X *ptr = new X is not allowed).
I've declared new, new[] operators private, but since I'm allocating X's objects through addX() I need to define them (operators). So, what's their definition should look like?
Hide the constructors, use a factory function:
class A
{
public:
static A* create() { return new A; }
static void destroy(A* a) { delete a; }
protected:
A() {}
A(const A&) {}
A& operator=(const A&) {}
};
This is pretty easy.
#include <iostream>
#include <new>
class X {
public:
static void addX()
{
X* p1 = new X;
delete p1;
}
private:
void* operator new(std::size_t sz)
{
std::cout << "custom new for size " << sz << '\n';
return ::operator new(sz);
}
void* operator new[](std::size_t sz)
{
return ::operator new(sz);
}
};
int main()
{
X::addX();
}
I am trying to use templatized object pool , i have trouble overloading the placement new operator. the new operator works with default constructor but not with non default ones. here i am pasting my simple code.
#include <boost/pool/object_pool.hpp>
#include <cstddef>
template<typename T>
class objectPool
{
public:
void* operator new (std::size_t num) { void *vp = _pool.malloc(); T *t = ::new(vp)T; return t; }
void* operator new[] (std::size_t num) { void *vp = NULL; assert(0); return vp; }
void operator delete (void *vp) { _pool.free(static_cast<T*>(vp)); return; }
void operator delete [] (void *vp) { assert(0); return; }
private:
static boost::object_pool<T> _pool;
};
template<typename T>
boost::object_pool<T> objectPool<T>::_pool;
class number : public objectPool<number>
{
long long _value1, _value2;
public:
number(long long value1, long long value2) : _value1(value1), _value2(value2) { return; }
~number(){ return; }
void print() { std::cerr<<"_value1:"<<_value1<<"_value2:"<<_value2; return; }
};
int
main(int ac, char **av)
{
number *n = new number(1000, 2000);
n->print();
delete n;
return 0;
}
Operator new does not call contructor, it allocates memory http://www.cplusplus.com/reference/new/operator%20new/
When you are using it, constructor get called:
//normal new
new T(a1, a2);
//placement new
new (na1, na2) T(a1, a2)
You should just remove new call in you new operator and return vp