Invictus
Invictus

Reputation: 4328

Error While creating a class whose object cant be created on stack but only on Heap?

I tried writing a code to create a class, whose object can only be created on heap but not stack. But During Compilation I got some linking error.

  # include<iostream>
  # include<stdio.h>
  # include<conio.h>

  using namespace std;

  class Rect
  { 
      int length;
      int breadth;
      Rect();

       public :
       Rect & operator = (const Rect&);       
       Rect(const Rect& abc)
       {
           cout<<"in copy const"<<"\n";        
       }

       ~Rect();
       int area_rect()          
       {
           return length*breadth;
       }

       void set_value(int a,int b);

       static Rect* instance()
       {     
           Rect* ptr=NULL;
           ptr=new Rect ;
           return ptr;
       }
   };

   void Rect::set_value(int a,int b)
   {
       length=a;
       breadth=b;
   }

   int main()
   {

       Rect* a= Rect::instance();
       a->set_value(10,3);
       cout << "area realted to object a : "  << a->area_rect() <<"\n"; 
       Rect* b=a;    
       b->set_value(10,4);
       cout << "area realted to object a : "  << a->area_rect() <<"\n"; 
       cout << "area realted to object b : "  << b->area_rect() <<"\n"; 
       delete b;
       getch();
       return 0;
   }       

I got the following error:

ccUfbaaa.o(.text+0x24f) In function `main':   [Linker error] undefined reference to `Rect::~Rect()' 
ccUfbaaa.o(.text$_ZN4Rect8instanceEv[Rect::instance()]+0x60) In function `ZN4Rect9area_rectEv':   [Linker error] undefined reference to `Rect::Rect()' 
ccUfbaaa.o(.text$_ZN4Rect8instanceEv[Rect::instance()]+0x60) ld returned 1 exit status .

I know I can make destructor private that Will allow object to be crated only on heap . But in that case how can i delete the created object ? And How can we correct this above error?

Upvotes: 1

Views: 176

Answers (2)

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 153830

The way you can enforce that your type can only be put on the heap but not on the heap is have a base class with a pure virtual destructor base and to make the destructr private: since the destructor isn't accessible to the full object, it can't be put on to the stack but it can be deleted through a pointer to the base. To prevent a derived class can be put on the stack (if this should be prevented, too) you want to make the type final (which is only available in C++2011, though):

struct A { virtual ~A() = 0; };
A::~A() {}

struct B final: A { private: ~B() {} };

int main()
{
    //B  berror; // ERROR: destructor not accessible
    B* b = new B;
    delete static_cast<A*>(b);
}

The fact some some of your members were declared but not defined was already mentioned in other answers to this questions.

Upvotes: 1

jgsogo
jgsogo

Reputation: 726

You just have to implement the default constructor and the destructor somewhere:

Rect::Rect():length(0),breadth(0) {};
Rect::~Rect() {};

and then, making public Rect::instance(), Rect::set_value(int, int) and Rect::area_rect(), will help

Upvotes: 3

Related Questions