2010-10-05 104 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; } 
};