2012-02-07 76 views
1

我试着编写一个代码来创建一个类,它的对象只能在堆上创建,但不能在堆栈上创建。但在编译期间,我得到了一些链接错误。错误创建一个类的对象不能在堆栈上创建,但只能在堆上创建?

# 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

您没有〜Rect()的实现,并且您没有默认构造函数... – 2012-02-07 20:24:56

回答

3

你只需要执行默认的构造函数和地方的析构函数:

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

,然后,使公共Rect::instance()Rect::set_value(int, int)Rect::area_rect(),将有助于

+0

使用初始化程序列表而不是进行分配。 – 2012-02-07 20:30:06

+1

编辑为@ kerrek-sb建议 – jgsogo 2012-02-07 20:34:39

+1

(另外,你不需要分号!:-)) – 2012-02-07 20:35:35

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

事实在这个问题的其他答案中已经提到了一些你的成员,但没有被定义。