2010-10-05 43 views
2

我與新的運營商已經取得了私人的某一等級的工作,這樣就得到一個實例的唯一方法是寫類實例的大小

Foo foo = Foo() 

寫作

Foo* foo = new Foo() 

不起作用。

但是,因爲我真的想它的指針,我模擬與以下:

Foo* foo = (Foo*)malloc(sizeof(Foo)); 
*foo = Foo(); 

,這樣可以測試指針是否爲空知道是否已經被初始化。

它看起來像它的工作原理,從實證檢驗,但有可能是沒有足夠的空間已被分配的malloc?或者別的東西變得有趣?

---編輯---

A未提及的背景下,因爲我本來就不是肯定他們爲什麼新的運營商被禁用。這個類是約束編程庫(gecode)的一部分,我認爲它可能被禁用,以強制指定模型的文檔化方式。

我不知道具體的數據類型成語,這看起來更合理。

即指定一個標準模型---在一切被指定爲在太空的派生類CDTs時分配方案可能被罰款---但對我來說,這些實例分別由特定的類創建,然後通過通過引用表示模型的類的構造函數。

關於原因,我沒有使用

Foo f; 
Foo *pf = &f; 

它會像做情況1以下,它拋出一個「回頭參照本地變量」警告

int& f() { int a=5; return a; } // case 1 
int& f() { int a=5; int* ap=&a; return *ap; } 
int& f() { int* ap=(int*)malloc(sizeof(int)); *ap=5; return *ap; } 

這警告在情況2中添加指針時消失,但我想這是因爲編譯器丟失了跟蹤。

所以,唯一的選擇就是情況下3(不提的是additionaly,ap是將只有一次當f被稱爲初始化類的成員,將爲空否則,是返回的唯一功能這種方式,我相信ap在這種情況下失去了它的意義,因爲compilier優化它(可能會發生?)

但我想這遠遠超出了原來的範圍現在的問題...

+0

爲什麼你真的想要一個指針呢?難道你不能做像Foo foo = Foo(); Foo * fooPtr = &foo; – Hogan 2010-10-05 16:46:13

+0

我可能是錯的,但這樣做對我來說似乎很奇怪。 'delete'也是私人的嗎?否則,你的代碼中會顯式地刪除'''',但不會''新建''。這很難追蹤。 – John 2010-10-05 16:48:17

+0

爲什麼不用'&foo'來獲取對象的地址?你爲什麼要做'malloc'? – Naveen 2010-10-05 16:48:51

回答

4

小心打破具體數據類型習語。

您試圖規避new運算符已被私有化的事實,即Concrete Data Type慣用法/模式。由於特定原因,new運營商可能被私有化,例如,設計的另一部分可能取決於這一限制。試圖繞過這個來動態分配類的一個實例,試圖規避設計,並可能導致其他問題或其他意外行爲。如果不徹底研究代碼以確保您瞭解對課程/代碼的其他部分的影響,我不會建議試圖繞過這一點。

具體的數據類型

解決方案

...

代表與計算模型,實現或編程語言緊密相關的代表抽象的對象,應該被聲明爲本地(自動或靜態)實例或成員實例。集合類(字符串,列表,集合)就是這種抽象的例子(雖然它們可能使用堆數據,但它們本身並不是堆對象)。它們是具體的數據類型 - 它們不是「抽象的」,而是像int和double一樣具體。

class ScopedLock 
{ 
    private: 
    static void * operator new (unsigned int size); // Disallow dynamic allocation 
    static void * operator new (unsigned int size, void * mem); // Disallow placement new as well. 
}; 
int main (void) 
{ 
    ScopedLock s; // Allowed 
    ScopedLock * sl = new ScopedLock(); // Standard new and nothrow new are not allowed. 
    void * buf = ::operator new (sizeof (ScopedLock)); 
    ScopedLock * s2 = new(buf) ScopedLock; // Placement new is also not allowed 
} 

ScopedLock對象不能與新的運營商的標準使用,不拋出異常新,和放置新動態分配的。

8

不要使用malloc與C++類。malloc是迪菲new稱爲班級的構造者,但malloc不重要。

你可以用幾種方法得到一個指針,但首先問自己爲什麼?你想動態分配對象嗎?你是否試圖將指針傳遞給其他函數?

如果你身邊路過的指針,你可能會更好通過引用來代替:

void DoSomething(Foo& my_foo) 
{ 
    my_foo.do_it(); 
} 

如果你真的需要指針(也許是因爲你不能改變的DoSomething實施),那麼你可以簡單地把指針自動:

Foo foo; 
DoSomething(&foo); 

如果你需要動態分配Foo對象,事情變得有點棘手。有人提出new操作private是有原因的。可能是一個非常好的理由。有可能是在Foo像工廠方法:

class Foo 
{ 
public: 
    static Foo* MakeFoo(); 
private: 
}; 

..in這種情況下你應該調用。否則,你將不得不編輯Foo本身的實現,這可能不是一件容易的事,也不是一件好事。

+0

在我的情況下沒有工廠方法,否則我會使用它們並從那裏獲取我的指針。類實例被初始化爲CDT(如Bert F.解釋過的),所以我猜這個構造函數實際上從來沒有被調用過(我會檢查這個)。所以我現在感覺很好(只要它有效)。 – Gzorg 2010-10-06 07:13:30

0

我沒有完全理解底層代碼。如果其他事情都可以,上面的代碼是正確的。從malloc()將分配足夠的空間,任何有趣的事情都不會發生。但切忌用奇怪的代碼和工作簡單明瞭:

Foo f; 
Foo *pf = &f; 
1

會從沒有被要求*foo構造發生結果的有趣的事情。它只有在POD(成員的簡單內置類型+無構造函數)時纔有效。否則,在使用賦值時,如果左側還不是該類的有效實例,則可能無法正確運行。

看來,你仍然可以有效地在堆中分配的實例與

Foo* p = ::new Foo; 

要限制一個類的實例是如何被創建,你可能會更好聲明構造函數(S)私有的,只能允許工廠函數調用它們。

0

把它包:

struct FooHolder { 
    Foo foo; 
    operator Foo*() { return &foo; } 
};