2012-02-07 81 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); 
} 

事實在這個問題的其他答案中已經提到了一些你的成員,但沒有被定義。