怎样禁止基类构造函数的调用?
有基类base,类derive从base派生,base和derive都有默认构造函数,当我new一个derive对象时,我想禁止基类构造函数的调用,只调用derive的构造函数,请问应该怎样做? 问题点数:50、回复次数:69Top
1 楼taodm((不能收CSDN社区短信息,请莫浪费精力))回复于 2006-11-07 10:46:20 得分 0
不可以!
C++规定,基类的构造函数一定会被调用,要么你显式指定了调哪个构造函数,要么会编译器自动调默认构造函数。
不调构造函数就不可以创建对象。
所以,请提你的原始需求。Top
2 楼dragonzxh(河马MiaMia~柯奶奶和黑爷爷的儿子叫柯南...~)回复于 2006-11-07 10:47:16 得分 0
设计有问题吧....
不要继承好了。..Top
3 楼dragonzxh(河马MiaMia~柯奶奶和黑爷爷的儿子叫柯南...~)回复于 2006-11-07 10:48:12 得分 0
你只能够控制基类的构造不是在外部被显式调用的。Top
4 楼goodluckyxl(被人遗忘的狗)回复于 2006-11-07 10:49:55 得分 0
class ba
{
public:
ba() {cout<<"ok"<<endl;}
};
class d:public ba
{
public:
d() {cout<<"d"<<endl;}
};
void main()
{
d* dd = (d*)malloc(sizeof(d));
}
malloc可以跳过构造 new是不行的Top
5 楼dragonzxh(河马MiaMia~柯奶奶和黑爷爷的儿子叫柯南...~)回复于 2006-11-07 10:51:53 得分 0
小狗....malloc当然不构造。...Top
6 楼dragonzxh(河马MiaMia~柯奶奶和黑爷爷的儿子叫柯南...~)回复于 2006-11-07 10:52:09 得分 0
丫是在犯路线主义错误。..Top
7 楼goodluckyxl(被人遗忘的狗)回复于 2006-11-07 10:54:15 得分 0
^_^Top
8 楼xhs1115(木亘)回复于 2006-11-07 10:59:01 得分 0
因设计需要,当new基类对象时,希望基类默认构造函数可以被调,但new派生类对象时,希望抑制基类默认构造函数的调用.Top
9 楼dragonzxh(河马MiaMia~柯奶奶和黑爷爷的儿子叫柯南...~)回复于 2006-11-07 11:01:32 得分 0
不需要基类构造就不要继承好了.干吗非要继承一个不允许调用其构造函数的基类呢。..Top
10 楼abblly(西边日出东边雨)回复于 2006-11-07 11:02:30 得分 0
因设计需要,当new基类对象时,希望基类默认构造函数可以被调,但new派生类对象时,希望抑制基类默认构造函数的调用.
-------------------
设计有问题,修改设计Top
11 楼akirya(坏[其实偶不是什么所谓的坏人])回复于 2006-11-07 11:47:55 得分 0
肯定调用基类的构造函数。Top
12 楼OOPhaisky(异化$渴望成功~~)回复于 2006-11-07 12:28:55 得分 0
当我new一个derive对象时,我想禁止基类构造函数的调用,只调用derive的构造函数,请问应该怎样做?
----------------------------------------------------------------------------------
这是不可能的,因为derived的构造函数肯定要调用基类的构造函数,否则无法构造基类成分。
至于goodluckyxl(被人遗忘的狗)的方法,如果用malloc,那么连derived的构造函数都不会被调用了,因为malloc没有对象语义。
Top
13 楼xhs1115(木亘)回复于 2006-11-07 14:39:10 得分 0
既然基类构造函数的调用无法避免,那么在基类构造函数中怎样判断当前构造的是派生类对象,从而跳过.Top
14 楼taodm((不能收CSDN社区短信息,请莫浪费精力))回复于 2006-11-07 14:44:27 得分 0
兄弟,你就别在歧途上越走越远了。
不如说说你的基类构造函数里有啥东西,让你不想让它执行吧。Top
15 楼sinall()回复于 2006-11-07 15:02:46 得分 0
呵呵,所谓继承——base对象是derived对象的一部分!!!
derived 它不是一个人在战斗!!!Top
16 楼dragonzxh(河马MiaMia~柯奶奶和黑爷爷的儿子叫柯南...~)回复于 2006-11-07 15:22:13 得分 0
他不是一个人!Top
17 楼lin_style(﹏.贾诩(某人语:矮子也高潮))回复于 2006-11-07 15:35:49 得分 0
设为纯虚的函数。试试Top
18 楼antoniusguo(anton)回复于 2006-11-07 19:57:37 得分 0
class base
{
private:
base(int);
public:
base();
};
class derive : public base
{
};Top
19 楼antoniusguo(anton)回复于 2006-11-07 20:01:06 得分 0
也不行Top
20 楼picturecn()回复于 2006-11-07 20:06:45 得分 0
是可以实现的,用虚拟集成实现。
虚拟集成是用在C++的多重集成中,最典型的一个案例是标准库<iostream>。
如下:
class base
{
public:
base();
//....
}
class derive :public virtual base
{
public:
derive();
}
//派生类构造函数
derive::derive()
:base() //你可以在这里控制
{}
虚拟集成要在派生类中手工(显示的)实例化基类,否则基类不会被构造,这也是虚拟集成同普通集成的一大区别。
Top
21 楼picturecn()回复于 2006-11-07 20:09:36 得分 0
虚拟集成应用主要是这样的:
class base
{
}
class A:public base
{
}
class B:public base
{
}
class C:public A,public B //此时如果不用虚拟集成,逻辑上将会有两个base被实例化,那么将来用那个呢?
{
}
Top
22 楼picturecn()回复于 2006-11-07 20:11:46 得分 0
在《C++ Primer》 3e中有一个panda同Zooanimal的案例,就是虚拟集成的。Top
23 楼zyyoung(倡导开源)回复于 2006-11-07 20:20:39 得分 0
把基类的构造声明为虚拟的构造函数Top
24 楼guochun(yingc)回复于 2006-11-07 20:51:05 得分 0
构造函数不能为虚拟Top
25 楼ysc918(白纸人生)回复于 2006-11-07 21:08:43 得分 0
能将基类的默认构造函数声明为虚函数吗?不能吧。Top
26 楼iambic()回复于 2006-11-07 21:10:59 得分 0
把基类去掉就可以了。Top
27 楼liumangxiong(陈世奎)回复于 2006-11-07 21:44:57 得分 0
设置成private的Top
28 楼dfkoko(xiaoyin)回复于 2006-11-07 22:17:53 得分 0
private就不能创建实例了Top
29 楼qxbnit(蓝灵)回复于 2006-11-07 22:27:28 得分 0
picturecn() 虚拟集成
-------------
说的不错!Top
30 楼xhs1115(木亘)回复于 2006-11-08 08:56:39 得分 0
已经解决,我是这么做的
class base
{
public:
base();
protected:
base(bool){}
//....
}
class derive :public base
{
public:
derive():base(true)
{
//....
}
}
这样当new derive时可以保证调用的空的基类构造函数.
谢谢各位的回应!
Top
31 楼taodm((不能收CSDN社区短信息,请莫浪费精力))回复于 2006-11-08 08:57:38 得分 0
呃,picturecn,你C++ Primer那章没仔细看完吧,3e P818。
非但解决不了楼主说的不调基类构造函数,还造成了不管派生多少层,每层的类都得显式指定这个虚基类的构造函数调用了。Top
32 楼taodm((不能收CSDN社区短信息,请莫浪费精力))回复于 2006-11-08 09:02:23 得分 0
楼主,你那个还叫继承嘛。狂汗一个!
继承是is-a的关系,全被你乱用了。Top
33 楼yunyu97()回复于 2006-11-08 09:34:57 得分 0
可以重写new操作符和delete操作符,当调用derive的时候用molloc分配空间并调用derive的构造然后将molloc出来的对象指针返回。当delete被调用的时候调用析构函数并free对象的指针。Top
34 楼lurenfu(具有中国特色的社会主义初级阶段,一百年不变)回复于 2006-11-08 10:23:52 得分 0
楼主的解决方案明显很无聊,你比申明几个不同的构造函数,根据需要调用不同的构造函数,这是很基本的东西,跟你所谓的需求完全不是那么回事Top
35 楼wd_6532(用frontpage写asp,jsp,php,ace)回复于 2006-11-08 12:01:03 得分 0
把base的构造函数设置为 protect的行吗?Top
36 楼wd_6532(用frontpage写asp,jsp,php,ace)回复于 2006-11-08 12:02:43 得分 0
哦,看了楼主的意思,protect并不行。
Top
37 楼FFSB()...()回复于 2006-11-08 12:03:56 得分 0
倒粪Top
38 楼iambic()回复于 2006-11-08 12:11:45 得分 0
太搞笑了,你干脆不要声明构造函数好了,这样就不会调用构造函数了是吧……Top
39 楼SJcinux(香卜裁)回复于 2006-11-08 12:31:01 得分 0
设计都有问题
胡拉拉Top
40 楼combojiang(combojiang)回复于 2006-11-08 12:43:50 得分 0
楼主如果早看了MFC类库,你就不会有这个问题了。
MFC类库中的基类的构造函数都是这么处理的,设为Protected。Top
41 楼al0n9(终于有四条内裤了)回复于 2006-11-08 14:12:41 得分 0
基本上,我觉得这是设计上的问题,应该重新调整设计。如果不能重新设计,也可以用以下方法:
最简单的方法:
1.修改基类的构造函数,增加一个标志变量,并设置默认值。
2.基类的构造函数里,判断这个标志变量是否等于默认值,如果相等,做原来的构造过程。如果不等于默认值,则什么也不做就退出。
3.直接生成基类对象时,不要为构造函数传递默认值,在从派生类构造函数传递给基类构造参数的时候,设置此标志变量为另外一个值。
class base {
public:
base(int pa1, int flag = 0) {
if (flag !=0 )
return;
// other process here
}
}
class derive:public base {
public:
derive(int p3):base(p3, 2) {
....
}
}
这样做的好处就是你只需要修改基类的构造函数和派生类的构造函数,其它已经有的,使用基类的代码不需要修改。缺点是,万一有人在生成基类对象的时候,为标志变量传一个值,会造成基本构造函数执行不完整。
另外一个办法:为基类增加一个新的构造函数,重载基类原来的构造函数,但是在这个新构造函数内什么也不做,并设置为protected,在派生类的构造函数中,调用这个新加的基类构造函数。
class base {
protected:
base(int) {}
public:
base(string name) {
.... // normal process here
}
}
class derive:public base {
public:
derive(int p3):base(1) {
....
}
}
这样做可以一定程度上,防止有人误用基类的构造函数,从而造成基类初始化不完整。Top
42 楼xwzxwz(怪物)回复于 2006-11-08 15:09:56 得分 0
鄙视问题解决不结贴的Top
43 楼gql_w()回复于 2006-11-08 17:26:38 得分 0
你的需求有严重的问题,放弃它~Top
44 楼wd_6532(用frontpage写asp,jsp,php,ace)回复于 2006-11-08 18:01:10 得分 0
al0n9,呵呵,你的方法,base的构造函数还是执行了。
楼主说的是不执行。Top
45 楼wd_6532(用frontpage写asp,jsp,php,ace)回复于 2006-11-08 18:04:16 得分 0
解决楼主的问题的办法就是 改变编译器的行为。
让父类在实例化的时候不自动调用基类的构造函数(我一直疑惑,是否是真的会自动调用基类构造函数,好像也是不调用吧)Top
46 楼yjbgwxf123()回复于 2006-11-08 20:29:04 得分 0
这是不可能办到的。Top
47 楼watermelontx(晨曦)回复于 2006-11-08 20:30:11 得分 0
虚函数看可不可以做到!Top
48 楼picturecn()回复于 2006-11-08 20:59:18 得分 0
to taodm(taodm)
===========================
是可以用虚拟集成做的,这样可以直接达到目的:派生类在实例化的时候编译器不会自己调用基类构造函数。Top
49 楼picturecn()回复于 2006-11-08 21:00:32 得分 0
to taodm(taodm)
================================
只不过虚拟集成通常不用在单集成,然而一般用户又不经常写自己的多集成类。Top
50 楼picturecn()回复于 2006-11-08 21:03:48 得分 0
to wd_6532(胜败有常)
解决楼主的问题的办法就是 改变编译器的行为。
==================
C++已经在语言设施中有这个功能了,不用改变编译器。Top
51 楼liu_chulong()回复于 2006-11-08 22:22:24 得分 0
好像是Effective C++第三版有讲的,把构造函数弄成私有的就行了Top
52 楼taodm((不能收CSDN社区短信息,请莫浪费精力))回复于 2006-11-09 08:54:22 得分 0
picturecn,你真的真的去看过P818?Top
53 楼fengfeiwuwq(寒烟翠)回复于 2006-11-09 09:32:22 得分 0
已经解决,我是这么做的
class base
{
public:
base();
protected:
base(bool){}
//....
}
class derive :public base
{
public:
derive():base(true)
{
//....
}
}
这样当new derive时可以保证调用的空的基类构造函数.
你这仅仅是重载了基类的构造函数,又在派生类构造函数中显示调用了重载的构造函数,因此在创建派生类实例的时候不会去调用基类的缺省构造函数,但是与你所说的设计“禁止基类构造函数调用”是两回事,很明显,你已经误导了大家。Top
54 楼onlinewan()回复于 2006-11-09 12:44:35 得分 0
定义为私有Top
55 楼zkkpkk(菜鸟爱GDI)回复于 2006-11-09 15:22:39 得分 0
malloc,真的很少用了Top
56 楼Godlikeme(我们所要做的不仅仅是抵制日货)回复于 2006-11-09 17:08:58 得分 0
呵呵,所谓继承——base对象是derived对象的一部分!!!
derived 它不是一个人在战斗!!!
-----------------------------------------
经典!!
Top
57 楼Fenris()回复于 2006-11-09 18:36:36 得分 0
to liu_chulong
可以吗 编译的时候会报错说 cannot access private member declared in class 'Parent' 吧Top
58 楼Stefine(CSDN最菜滴猩猩)回复于 2006-11-09 21:54:05 得分 0
It's impossible
需求问题,重新设计...
你那样重载一个空的构造函数来让派生类显示调用有何意义....
肯定一点:你标题的那样禁止基类的构造函数调用 是不可能滴....Top
59 楼jronald(深白色)回复于 2006-11-10 06:56:34 得分 0
C++不是这么玩滴,如果你想玩他,那就玩吧Top
60 楼chary8088(天使鱼儿)回复于 2006-11-10 08:39:02 得分 0
al0n9(为四个裤叉努力ing) ( )
这样就可以保证基类的构造函数不起作用,最终效果是一样的Top
61 楼aya331(菜菜小鸟)回复于 2006-11-10 21:29:20 得分 0
to taodm(taodm)
==============================
抱歉楼主,也抱歉大家,抱歉taodm(taodm),怪我学习不求甚解,用在这个问题上用虚继承是错误的,我的方法行不通,抱歉。Top
62 楼xyz666((我是一只怪怪虫up ~up))回复于 2006-11-10 22:01:35 得分 0
构造函数不可能是private和虚函数了吧?Top
63 楼wd_6532(用frontpage写asp,jsp,php,ace)回复于 2006-11-11 12:04:50 得分 0
呵呵,所谓继承——base对象是derived对象的一部分!!!
derived 它不是一个人在战斗!!!
-----------------------------------------
经典!!
========================
把战斗去掉。
derived 它不是一个人!!!
Top
64 楼wjlsmail(小脖领)回复于 2007-01-27 16:24:27 得分 0
Perhaps no wayTop
65 楼lidongri(海浪 源码之前了无秘密)回复于 2007-01-27 16:32:52 得分 0
有个简单的方法,
virtual base() = 0;
这样子类就不会调用父类的构造函数了。Top
66 楼htqx(航天奇侠)回复于 2007-01-27 17:22:30 得分 0
楼主自己找到了我认为她需要的方法.
其实楼主并不是想不要调用基类的构造函数,而是不调用默认的构造函数.这是楼主言外之音(也叫口齿不清吧)
Top
67 楼steelfrog(叶落无心)回复于 2007-01-27 20:52:27 得分 0
建一个虚函数,在构造函数里使用,
是不是可以呢?Top
68 楼roydux(后台运行中-http://www.LeadNT.org 大家一起来写吧)回复于 2007-01-27 20:55:22 得分 0
把基类的构造函数写成private?Top
69 楼sarh2onacy()回复于 2007-01-28 00:45:20 得分 0
因设计需要,当new基类对象时,希望基类默认构造函数可以被调,但new派生类对象时,希望抑制基类默认构造函数的调用.
=======================================================================================有一个办法可以实现:
class A
{
public:
A(){//do somethin}
A(int i){//do nothing}
};
class B:public A
{
B():A(0){//do something}
};
class B的其它构造函数也要写同样的"成员初始化列表"!这样即可避免在构造B时,调用A的默认构造函数.
不知道能不能解决楼主的问题.但是强烈建议重新考虑继承体系.感觉设计上有点问题.Top




