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.
Related
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
In my constructor I initialize a field. The field is destroyed just after the initialization.
Here's my code and my test:
A.hpp
class A {
private:
T t;
public:
A();
~A();
void add(string name, string num);
};
A.cpp
A::A() {
cout << "Creating A\n";
t = T(100);
cout << "End\n";
}
void A::add(string name, string num) {
cout << "calling add in A\n";
t.add(name, num);
}
T.hpp
class T {
private:
E * t;
public:
T(int size=100);
~T();
void add(std::string name, std::string num);
T.cpp
T::T(int size) : size(size) {
t = new E[size];
}
T::~T() {
cout << "Destroying\n";
// delete[] t; // if I don't comment this I get Segfault when calling add method
}
void T::add(string name, string num){
E e = E(name, num);
t[0] = e;
}
main.cpp
int main(int argc, char* argv[]) {
A a;
a.add("name", "num");
}
Output
Creating A
Destroying
End
calling add in A
Destroying
This code:
t = T(100);
is, equivalently:
T _temp(100);
t = _temp;
Which helps visualize why some T is getting destroyed. It's not your t, it's the temporary T(100). That's why you see two prints of "Destroying"... one for the temporary, and one for A::t.
To avoid the spurious destruction, use an initializer list:
A::A()
: t(100)
{ }
I've just started learning C++ and stumbled across this problem..
I've written this abstract class with pure virtual destructor:
#ifndef ANIMAL
#define ANIMAL
#include <string>
using namespace std;
class Animal {
public:
Animal();
virtual ~Animal() = 0;
Animal(string name, int age);
virtual string says() = 0;
void setName(string name);
void setAge(int age);
string getName() const;
int getAge() const;
private:
int _age;
string _name;
};
inline Animal::~Animal() { }
Created dynamically and destroyed like this...
Animal** animalArray = new Animal*[10];
animalArray[0] = new Dog(name, age);
animalArray[1] = new Cat(name, age);
animalArray[2] = new Owl(name, age);
delete[] animalArray;
and I am left wondering if an Animal object is created dynamically and then destroyed, will the _age and _name members get destroyed properly since the destructor for Animal class is empty? If so, why?
Thanks :D
In the example you posted, you're actually not destroying everything correctly. In the line
delete[] animalArray;
you are deleting an array of Animal*s. Note that this does not automatically destroy the things being pointed to! You would have to do:
for(int i = 0; i < 3; ++i)
delete animalArray[i];
delete[] animalArray;
This destroys each element, then destroys the container.
Now, your actual question is asking whether the private member variables are going to be cleanly destroyed. The answer is yes--after your destructor runs, any statically allocated variables' destructors will also be called by the compiler. It is their obligation to clean up after themselves. When you're doing polymorphism as in your example, the (empty) destructor Animal::~Animal will indeed be called.
Note that this carries the same warning as the code above: if you instead have
string* _name;
that you dynamically allocate in the constructor (with new), then the string* will be destroyed, but the pointed to string will not be. So in that case, you would have to manually call delete to properly clean up.
yes they will. By making the Animal destructor virtual (or pure virtual in your case, doesn't matter regarding your question) you make sure that everything is properly destroyed when using Animal as a base class.
The destructor of Animal will call the destructor for each of it's members in reverse initialization order (i.e. it will destroy _name first and _age afterwards) and thereby makes sure that everything is properly freed.
According to Herb Sutter you cannot instantiate a class with a pure virtual destructor unless it also has a body. The reason is that any derived class will need to call that destructor after its own destructor is finished.
We can verify this with at least one compiler: http://ideone.com/KcwL8W
#include <string>
class Animal
{
public:
virtual ~Animal() = 0;
std::string _name;
};
class Dog : public Animal
{
};
int main() {
Animal* pet = new Dog;
delete pet;
return 0;
}
/home/abDVbj/cc8ghrZk.o: In function `Dog::~Dog()':
prog.cpp:(.text._ZN3DogD2Ev[_ZN3DogD5Ev]+0xb): undefined reference to `Animal::~Animal()'
/home/abDVbj/cc8ghrZk.o: In function `Dog::~Dog()':
prog.cpp:(.text._ZN3DogD0Ev[_ZN3DogD0Ev]+0x12): undefined reference to `Animal::~Animal()'
it will , destructor is not really destroy the object you created , it is called before the object being destroied, if you have not new something in constructor , there is no need for you to delete it.
I try to finger out a sample to prove
when using string(with a pointer member) object as member variable, its destructor will be called, even we do nothing in the class's destructor
so I tried to used a user-defined String as object, so it is easy for us to write some log in the destructor.
it outputs:
constructor is called
constructor is called
constructor is called
operator constructor is called
destructor is called
operator constructor is called
destructor is called
virtual ~Dog()
virtual ~Animal()
destructor is called
it show is when virtual ~Animal() is called , the string object'destructor in the Animal class is called.
we can change the string object to string*(using new in construtor) while still doing nothing in the destructor , and we will see the string's destructor is not called
#include <iostream>
#include <string.h>
using namespace std;
class String{
public:
String(const char *str = NULL);
String(const String &str);
~String();
String operator+(const String & str);
String & operator=(const String &str);
bool operator==(const String &str);
int Length();
friend ostream & operator<<(ostream &o,const String &str);
String SubStr(int start, int end);
private:
char * charArray;
};
String::String(const char *str)
{
if(str == NULL){
charArray=new char[1];
charArray[0]='\0';
}else{
charArray=new char[strlen(str)+1];
strcpy(charArray,str);
}
std::cout<< "constructor is called" << std::endl;
}
String::String(const String &str)
{
std::cout<< "constructor is called" << std::endl;
charArray = new char[strlen(str.charArray)+1];
strcpy(charArray,str.charArray);
}
String::~String()
{
std::cout<< "destructor is called" << std::endl;
delete [] charArray;
}
String String::operator+(const String &str)
{
String res;
delete [] res.charArray;
res.charArray = new char[strlen(charArray)+strlen(str.charArray)+1];
strcpy(res.charArray,charArray);
strcpy(res.charArray+strlen(charArray),str.charArray);
return res;
}
String & String::operator=(const String &str)
{
if(charArray == str.charArray)
return *this;
delete [] charArray;
charArray = new char[strlen(str.charArray)+1];
strcpy(charArray,str.charArray);
std::cout<< "operator constructor is called" << std::endl;
return *this;
}
bool String::operator==(const String &str)
{
return strcmp(charArray,str.charArray) == 0;
}
int String::Length()
{
return strlen(charArray);
}
ostream & operator<<(ostream &o, const String &str)
{
o<<str.charArray;
return o;
}
String String::SubStr(int start, int end)
{
String res;
delete [] res.charArray;
res.charArray = new char[end-start+1];
for(int i=0; i+start<end; i++){
res.charArray[i]=charArray[start+i];
}
res.charArray[end-start] = '\0';
return res;
}
class Animal {
public:
Animal();
virtual ~Animal()=0;
Animal(String name, int age);
public:
int _age;
String _name;
};
Animal::~Animal(){
std::cout << "Animal::~Animal()" << std::endl;
}
Animal::Animal(String name, int age)
{
this->_name = name;
this->_age = age;
}
class Dog :public Animal
{
public:
virtual ~Dog() {
std::cout << "virtual ~Dog()" << std::endl;
};
Dog(String name, int age):Animal(name,age)
{
this->_name = name;
this->_age = age;
}
};
int main(){
Animal* p = new Dog( String("dog"),1);
delete p;
return 0;
}
This code works appropriately if I don't use and then delete a pointer for the base class Output. The destructor for Output is called and seems to work appropriately. Am I missing something here?
// multiple inheritance
// Testing overload of muliple inheritance of pure virtual functions.
#include <iostream>
#include <string>
using namespace std;
class Polygon {
protected:
int width, height;
public:
Polygon (int a, int b) : width(a), height(b) {}
~Polygon() = default;
virtual int area() = 0;
};
class Output {
private:
string* myString;
public:
Output() {
myString = nullptr;
}
Output(const string& s) {
myString = new string(s);
}
// This seems to work, but ther core dump happens right afterwards.
~Output() {
cout << "delete called with: " << myString << '\n';
if (myString != nullptr)
delete myString;
}
virtual int area() = 0;
void print () {
cout << *myString << this->area() << '\n';
}
};
class Rectangle: public Polygon, public Output {
public:
Rectangle (int a, int b) : Polygon(a,b), Output{"A Rectangle's area is: "} {}
int area () {
return width*height;
}
};
class Triangle: public Polygon, public Output {
public:
Triangle (int a, int b) : Polygon{a,b}, Output{"A Triangle's area is: "} {}
int area ()
{ return width*height/2; }
};
int main () {
Output * ptr1 = new Rectangle(4,5);
Output * ptr2 = new Triangle(4,5);
ptr1->print();
ptr2->print();
// Causes core dump.
delete ptr1;
delete ptr2;
return 0;
}
There are several major issues with this code:
First, you should not use multiple inheritance for this. It is completely unnecessary and will lead to very difficult to track down bugs.
Second, you do not need to test for nullptr before deleting a pointer - it is redundant as delete already does that.
Third, neither of your base classes has a virtual destructor. (your current error)
Forth, you are violating the Rule of 3 in your Output class (and likely will need to use it in all of them).
Fifth, assuming string means std::string. There is no reason for it to be a string* - just use std::string and avoid having to allocate and deallocate it.
I didn't fix your design issues, but your memory access and polymorphic issues are fixed here.
#include <iostream>
#include <string>
using namespace std;
class Polygon
{
protected:
int width, height;
public:
Polygon (int a, int b) : width(a), height(b) {}
virtual ~Polygon() { } // needed!
virtual int area() = 0;
};
class Output
{
private:
std::string myString; // no need to be a pointer
public:
Output() { }
Output(const string& s) : myString(s) { }
virtual ~Output() { } // also needed!
virtual int area() = 0;
void print () {
cout << myString << this->area() << '\n';
}
};
class Rectangle: public Polygon, public Output
{
public:
Rectangle (int a, int b) : Polygon(a,b), Output{"A Rectangle's area is: "} {}
int area () {
return width*height;
}
};
class Triangle: public Polygon, public Output
{
public:
Triangle (int a, int b) : Polygon{a,b}, Output{"A Triangle's area is: "} {}
int area ()
{ return width*height/2; }
};
int main ()
{
Output * ptr1 = new Rectangle(4,5);
Output * ptr2 = new Triangle(4,5);
ptr1->print();
ptr2->print();
// Causes core dump.
delete ptr1;
delete ptr2;
return 0;
}
EDIT: An example of a better way to implement the desired program can be found here.
Your Output and Polygon class destructors should be virtual also:
class Output {
private:
std::string* myString;
public:
// ...
virtual ~Output() {
// ^^^^^^^
}
};
Also note: Instead of using a std::string* pointer, you can simply use a std::string myString; member:
private:
std::string myString;
and leave behind bothering around with getting new string() and delete myString; right for any cases.
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