怎样定义一个基类,使其派生类只能通过new实例化?
注意,不能对派生类的加以语言之外的限定。 问题点数:100、回复次数:24Top
1 楼wlz47(秋水沉舟)回复于 2002-04-18 22:56:48 得分 10
酱紫不知道合不合你的要求
class base
{
private:
virtual ~base() {}
public:
base() : i(0){};
int i;
};
//*
class derived : public base
{
public:
void* operator new(size_t)
{
return new(derived);
}
};
//*/
void main()
{
derived d; // wrong
derived* pd = new derived; // OK
}
Top
2 楼wlz47(秋水沉舟)回复于 2002-04-18 22:58:52 得分 10
"注意,不能对派生类的加以语言之外的限定"
对不起,这句没看见,let me again think think.Top
3 楼wlz47(秋水沉舟)回复于 2002-04-18 23:02:19 得分 0
不重载继承类的new操作符好像也可以:
class base
{
private:
virtual ~base() {}
public:
base() : i(0){};
int i;
};
class derived : public base
{
public:
/* void* operator new(size_t)
{
return new(derived);
}
*/
};
void main()
{
derived d; // wrong
derived* pd = new derived; // OK
}
Top
4 楼anrxhzh(百宝箱)回复于 2002-04-18 23:05:00 得分 10
More Effective C++ Item 27: Requiring or prohibiting heap-based objects 中讲得很透彻。
只需要将基类的析构函数声明为protected即可,例如:
class HeapObject {
public:
//constructor
...
// pseudo-destructor (a const member function, because
// even const objects may be destroyed)
void destroy() const { delete this; }
private:
~HeapObject();
};
Top
5 楼wlz47(秋水沉舟)回复于 2002-04-18 23:10:43 得分 10
还是不行,delete 继承类对象指针时,因为继承类对象没有权限调用基类的析构函数而导致derived对象不能析构,故无法通过编译。
分特,let me again think think.Top
6 楼wlz47(秋水沉舟)回复于 2002-04-18 23:18:01 得分 0
难啦Top
7 楼wlz47(秋水沉舟)回复于 2002-04-18 23:41:05 得分 10
用设置某成员函数存取权限的方法恐怕不太可能吧。
因为你的要求是矛盾的,要达到你的要求恐怕非得对继承类动手脚才行Top
8 楼prototype(原型)回复于 2002-04-19 04:46:44 得分 10
anrxhzh(百宝箱) is right. make your ctors private/protected. this is a routine method to demand that objects can be only created in heap.Top
9 楼heming_zs()回复于 2002-04-19 09:05:38 得分 5
其实不难,将基类的constructor function 设为private,然后重载new操作副,
class HeapObject{
private:
HeapObject();
public:
virtual ~HeapObject();
HeapObject * operator new(size_t){this=(HeapObject*)malloc(sizeof(HeapObject);return this;}
}
Top
10 楼anrxhzh(百宝箱)回复于 2002-04-19 10:13:29 得分 5
to wlz47(秋水沉舟):
我给的示例代码有误,要将
private:
~HeapObject();
改为
protected:
~HeapObject();
很抱歉,给你带来了麻烦。Top
11 楼LionEagle(LionEagle)回复于 2002-04-19 10:59:29 得分 10
to anrxhzh(百宝箱):
~HeapObject不能设为virtual,否则用new也会被阻止,因为~HeapObject没有定义,而建立vtbl需要~HeapObject的定义Top
12 楼prototype(原型)回复于 2002-04-19 12:10:18 得分 5
sorry. didn't read 'anrxhzh(百宝箱)'s posts carefully.
correct: it should be 'constructor' (not destructor) that should be declared as private/protected.Top
13 楼anrxhzh(百宝箱)回复于 2002-04-19 14:26:32 得分 5
More Effective C++ Item 27: Requiring or prohibiting heap-based objects 中介绍的方法只能针对单个类,无法针对整个类层次,下面是我给出的完整示例:
class HeapObject {
public:
//constructor
//...
// pseudo-destructor (a const member function, because
// even const objects may be destroyed)
void destroy() const{ delete this; } ;
protected:
virtual ~HeapObject(){};
};
class A:public HeapObject{
};
int main()
{
//HeapObject h; //compile error
HeapObject * p = new HeapObject;
p->destroy();
A a; // ok
return 0;
}
当然,如果把构造函数声明为protected\private也是一样的,不过由于构造函数可能不止一个,所以没有上面的方法简洁。
好像很难找出针对整个类层次的通用方法。Top
14 楼Fantasia(幻想曲)回复于 2002-04-20 02:14:36 得分 0
多谢各位的热心讨论!
其实单个类要控制只能在堆上分配不难,难的是要通过基类控制其子类也只能在堆上分配,anrxhzh(百宝箱) 上面的代码并没有达到要求。
关于限定条件,就是说不能要求派生类如何声明自己的构造函数、析构函数,也不能假定它通过一个destroy函数销毁(最好是通过delete),唯一的要求就是它要从指定的基类派生。这一点上,wlz47(秋水沉舟)理解是很正确的。他没有找到解,我也趋向认同无解。但是否能够确认这一点,还需要各位仁者见仁、智者见智了。帖子我会晚两天再结。Top
15 楼tang1975(tangtang)回复于 2002-04-20 10:42:17 得分 0
无解
or template?
Let me install Chinese IME first:)Top
16 楼hongbo_liu(bobo)回复于 2002-04-22 13:57:49 得分 0
gzTop
17 楼elvahuang(熊熊)回复于 2002-04-22 14:16:29 得分 0
不懂??!!为什么可以?
TO wlz47(秋水沉舟)
?????????????????????????
愿哪位高手说说?Top
18 楼elvahuang(熊熊)回复于 2002-04-22 14:21:29 得分 0
还有就是将析构函数私有化?????什么意思??
在More Effictive C++ 中有讲?
Top
19 楼lengkuazhong()回复于 2002-04-22 15:36:33 得分 0
哪有Effective C++Top
20 楼Fantasia(幻想曲)回复于 2002-04-23 23:46:06 得分 0
看来没人再感兴趣,作无解吧。Top
21 楼elvahuang(熊熊)回复于 2002-04-26 17:43:14 得分 0
#include "iostream.h"
//after refreshing's problem
//base class "re" means "refresh"
class rebase
{
public:
virtual ~rebase()
{
cout<<"in rebase destor"<<endl;
}
protected:
rebase()
{
cout<<"in rebase ctor"<<endl;
}
};
//derived class
class rederived:public rebase
{
public:
~rederived() //it is virtual actually!!!!
{
cout<<"in derived destor"<<endl;
}
//void* operator new(size_t size)
//{
// return ;
//}
static rederived* MakeObject() //here must show to our user,if they get
{ //the return pointer,they must delete it when
rederived* pred=new rederived; //they don't want to use it wholely!!
return pred;
}
private:
rederived():rebase() //here's base must be visible!!!
{ //and in class base base()mustn't be visible in extern!!
//so base() must be protected!!and here ":base()"may not write out!!
cout<<"in derived ctor"<<endl;
}
};
//main
void main()
{
// rebase b; is wrong!!
// rederived d; is wrong!!
rederived* pd=rederived::MakeObject();
delete pd;
}
#include "iostream.h"
//after refreshing's problem
//base class "re" means "refresh"
class rebase
{
public:
virtual ~rebase()
{
cout<<"in rebase destor"<<endl;
}
protected:
rebase()
{
cout<<"in rebase ctor"<<endl;
}
};
//derived class
class rederived:public rebase
{
public:
~rederived() //it is virtual actually!!!!
{
cout<<"in derived destor"<<endl;
}
//void* operator new(size_t size)
//{
// return ;
//}
static rederived* MakeObject() //here must show to our user,if they get
{ //the return pointer,they must delete it when
rederived* pred=new rederived; //they don't want to use it wholely!!
return pred;
}
private:
rederived():rebase() //here's base must be visible!!!
{ //and in class base base()mustn't be visible in extern!!
//so base() must be protected!!and here ":base()"may not write out!!
cout<<"in derived ctor"<<endl;
}
};
//main
void main()
{
// rebase b; is wrong!!
// rederived d; is wrong!!
rederived* pd=rederived::MakeObject();
delete pd;
}
这样行吗????
Top




