3

为了实现引用计数,我们使用了一个IUnknown-like 接口和一个智能指针模板类。该接口实现了所有引用计数方法,包括Release()

void IUnknownLike::Release()
{
   if( --refCount == 0 ) {
       delete this;
   }
}

智能指针模板类有一个复制构造函数和一个赋值运算符,它们都接受原始指针。因此用户可以执行以下操作:

 class Class : public IUnknownLike {
 };

 void someFunction( CSmartPointer<Class> object ); //whatever function
 Class object;
 someFunction( &object );

并且程序运行到未定义的行为 - 对象被创建时引用计数为零,智能指针被构造并将其碰撞到 1,然后函数返回,智能指针被破坏,调用Release()导致delete堆栈分配的变量。

用户还可以执行以下操作:

struct COuter {
    //whatever else;
    Class inner;// IUnknownLike descendant
};
COuter object;
somefunction( &object.Inner );

再一次没有创建的对象newdeleted。处于最佳状态的未定义行为。

有没有办法改变IUnknownLike接口,以便用户被迫使用new创建所有派生的对象IUnknownLike- 直接派生和间接派生(在最派生和基础之间的类)?

4

3 回答 3

1

将构造函数设为私有并编写一个使用 new 的静态成员函数

class IUnknownLike{
public:
  static IUnknownLike * createIUnknownLike(); { return new IUnknownLike(); }

private:
  IUnknownLike (); // private ctor
};

IUnknownLike* obj = createIUnknownLike();
于 2010-05-14T11:38:37.497 回答
1

您可以使 Base 类的析构函数受保护和智能指针类成为他的朋友。

因此,用户将无法在堆栈上创建类的实例。他们必须使用 operatornew和 smart_pointer 类,这将调用 release 和 delete。

于 2010-05-14T11:57:23.177 回答
0

如果您真的打算为这么多类执行此操作,请使用宏来创建工厂方法。就像是:

#define FACTORY(NAME) protected: NAME();\
public: static NAME* create ## NAME(){ return new NAME(); }

如果你想将参数传递给构造函数,你必须变得更漂亮。

另一种方法是实现 COM 的其余部分,并让每个类向中央对象创建系统注册一个工厂函数。虽然是一个有趣的练习,但这一切听起来都是个糟糕的主意。

于 2010-05-14T13:59:22.013 回答