错误创建一个类,其对象无法在堆栈上创建但仅在堆上创建?

时间:2012-02-07 20:22:21

标签: c++

我尝试编写代码来创建一个类,其对象只能在堆上创建,但不能 堆。但是在编译期间我遇到了一些链接错误。

  # 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;
   }       

我收到以下错误:

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 .

我知道我可以使析构函数私有,只允许在堆上创建对象。但在那种情况下,我该如何删除创建的对象?我们如何纠正上述错误?

2 个答案:

答案 0 :(得分:3)

您只需要在某处实现默认构造函数和析构函数:

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

然后,公开Rect::instance()Rect::set_value(int, int)Rect::area_rect()会有所帮助

答案 1 :(得分:1)

你可以强制你的类型只能放在堆上但不能放在堆上的方法是有一个带有纯虚析构函数库的基类,并使destructr成为私有的:因为析构函数不能被访问完整对象,它不能放在堆栈上,但可以通过指向基础的指针删除它。为了防止派生类可以放在堆栈上(如果这也应该被阻止)你想要创建类型final(仅在C ++ 2011中可用):

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);
}

在这些问题的其他答案中已经提到了一些成员被宣布但未被定义的事实。