| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 926 人关注过本帖
标题:关于继承和派生代码
只看楼主 加入收藏
sunflower44
Rank: 1
等 级:新手上路
帖 子:23
专家分:1
注 册:2011-8-15
结帖率:80%
收藏
已结贴  问题点数:15 回复次数:15 
关于继承和派生代码
先上代码:
#include <iostream.h>
        class Base {
        public:
          Base(){ a=0;cout<<"Base缺省构造函数\n"; }
          Base(int i){ a=i;cout<<"Base带参构造函数\n"; }
          void print(){ cout<<"a="<<a<<","; }
          int Geta(){ return a; }
        private:
          int a;
        };
        class Derived:public Base {
        public:
          Derived(){ b=0;cout<<"Derived缺省构造函数\n"; }
Derived (int i,int j,int k);
          void print();
        private:
          int b;
          Base Ba;                      //子对象或称为内嵌对象
        };
        Derived::Derived(int i,int j,int k):Base(i), Ba(j),b(k)
  { cout<<"Derived带参构造函数\n"; }
        void Derived::print()
        {  Base::print();              //调用基类Base的print()函数
cout<<"b="<<b<<",Ba.a="<<Ba.Geta()<<endl;
        }
        void main()
        {  Derived d1,d2(5,3,7);
d1.print();  d2.print();
        }
运行结果如何?
搜索更多相关主题的帖子: 函数 class private include public 
2011-08-17 09:51
xg5699
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:140
专家分:522
注 册:2011-7-27
收藏
得分:8 
Base缺省构造函数
Base缺省构造函数
Derived缺省构造函数
Base带参构造函数
Base带参构造函数
Derived带参构造函数
a=0,b=0,Ba.a=0
a=5,b=7,Ba.a=3

都不结贴我郁闷那!
2011-08-17 11:32
jcw08120110
Rank: 8Rank: 8
来 自:南京
等 级:蝙蝠侠
帖 子:272
专家分:742
注 册:2009-6-8
收藏
得分:8 
尝试用默认参数解决这种多余的重载构造函数;
程序代码:
#include <iostream.h>
class Base {
public:
    Base(){ a=0;cout<<"Base缺省构造函数\n"; }
    Base(int i=0){ a=i;cout<<"Base带参构造函数\n"; }
    void print(){ cout<<"a="<<a<<","; }
    int Geta(){ return a; }
private:
    int a;
};
//-------------------------------------------------------------
class Derived:public Base {
public:
    Derived (int i=0,int j=0,int k=0):Base(i), Ba(j),b(k)
{ 
    cout<<"Derived带默认参构造函数\n";
}
    void print();
private:
    int b;
    Base Ba; //子对象或称为内嵌对象
};
//-------------------------------------------------------------
void Derived::print()
{
    Base::print();//调用基类Base的print()函数
    cout<<"b="<<b<<",Ba.a="<<Ba.Geta()<<endl;
}
//--------------------------------------------------------------
void main()
{
    Derived d1,d2(5,3,7);
    d1.print();
    d2.print();
}

图片附件: 游客没有浏览图片的权限,请 登录注册

君生我未生 我生君以老
2011-08-17 16:46
xg5699
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:140
专家分:522
注 册:2011-7-27
收藏
得分:0 
回复 3楼 jcw08120110
默认参数只有简单,我感觉是故意这么写的,程序目的就是给程序员打基础,
在程序中多余的构造函数并不是重载(我想你的意思应该是重复),我个人认为此构造函数并不多余,
而且很有意义.如果真要说程序很多地方多余,那我觉得对于输出的结果在程序中创造类也是多余的.
第一个构造函数就不多说了,派生类创造一个对象会自动调用基类的构造函数
第二个重复的构造函数又是哪里来的呢?向日葵44我想你肯定知道,在上次你发的贴的程序里已经很
明确的说明了一个类中包含另一个类的对象时会自动调用该类的构造函数或者是带参构造函数


其实我感觉这不是此程序中关键的,关键的一部分是在这里
 Derived (int i=0,int j=0,int k=0):Base(i), Ba(j),b(k)
在程序中不知道仔细的人有没有发现创建d1时
Base缺省构造函数
Base缺省构造函数
Derived缺省构造函数

调用了3个默认构造函数
但创建d2时为什么没有Base类的默认构造函数?
Base带参构造函数
Base带参构造函数
Derived带参构造函数
我们知道无论派生类创建的对象是带参还是无参都会调用基类的默认构造函数,但此程序却没有
可以不创建d1只创建d2的朋友会发现创建d2时根本不会在调用Base的默认构造函数了,调用的是Base带参造函数
根据这个例子我们又可以发现了新的东西,那就是在派生类初始化基类的构造函数
:Base(i)
那么系统就不会在
调用基类的默认构造函数了.而是根据程序员初始化的意愿来执行



[ 本帖最后由 xg5699 于 2011-8-17 17:55 编辑 ]

都不结贴我郁闷那!
2011-08-17 17:28
jcw08120110
Rank: 8Rank: 8
来 自:南京
等 级:蝙蝠侠
帖 子:272
专家分:742
注 册:2009-6-8
收藏
得分:0 
回复 4楼 xg5699
4楼你的意思是不是说的是:Derived的构造参数列表调用了base的有参构造函数;从而不会去调用默认构造函数;也就是说我屏蔽掉了默认构造函数的实现;另外创建d1时也屏蔽掉了默认构造函数;从而使你认为并不多余的构造函数完全没有作用;
虽然有些地方默认构造函数确实很有作用;
比如基类中如果自定义了一个有参构造函数;而忽略了默认构造函数;在它的派生类的中若使用默认构造函数;那么执行派生类中的默认构造函数时就会转而调用基类的构造函数,不过当发现只有有参构造函数而没有与他匹配的默认构造函数就会出错; 但是如果基类的有参构造函数使用默认参数,那么这种情况就不是错误了;所以我说带默认参数的有参构造函数基本上可以代替默认构造函数;减少了代码量!我觉得这是个人编程风格问题,而不是什么错误;就像我使用变量和指针时我喜欢初始化,在定义的时候就先赋给他一个默认值;至少我觉得这样的风格能减少错误的发生;
下面的是错误的例子:
程序代码:
#include<iostream>
using namespace std;
class a{
    int i;
public:
    a(int aa){i=aa;}
};
class b:public a{
    int j;
};

void main()
{
    b cla;
}

这里是对的例子:
程序代码:
#include<iostream>
using namespace std;
class a{
    int i;
public:
    a(int aa=0){i=aa;}   // 比上面多了一个默认参数;
};
class b:public a{
    int j;
};

void main()
{
    b cla;
}


[ 本帖最后由 jcw08120110 于 2011-8-18 11:13 编辑 ]

君生我未生 我生君以老
2011-08-18 11:01
xg5699
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:140
专家分:522
注 册:2011-7-27
收藏
得分:0 
回复 5楼 jcw08120110
学习了!的确是这样
但是为什么使用默认参数就不会报错呢?按理说还是应该调用基类的默认构造函数,但在有参构造函数中加了一个默认值反而
调用的却是带参构造函数,这是怎么一回事呢?

而且我觉得带参构造函数使用默认参数会和无参默认构造产生两义性,比如
程序代码:
#include<iostream>
using namespace std;
class a{
    int i;
public:
    a(){}; //增加一个默认构造函数就不能通过编译.
   a(int aa=0){i=aa;cout<<"带参构造函数"<<endl;}   // 比上面多了一个默认参数;
};
class b:public a{
    int j;

};

void main()
{
    b cla;
}

给我的感觉好象是使用默认参数把带参的构造函数直接变成了(无参的)默认构造函数了!才会和默认构造函数产生两义性
也就是说
a(int aa=0){i=aa;cout<<"带参构造函数"<<endl;}   
它已经不是带参构造函数了,就是默认构造函数!所以创建cla时不会出错.那就是为什么加了一个默认构造函数却不行了.
a(int aa=0)它其实就是a(){int aa=0;}二者功能上是相等的,但编译上却不相等!当然这只是我个人认为,如果真是这样,
当然是写a(){int aa=0;}看的清楚(我个人认为),因为这样就能把概念搞清楚,其它程序员一看就知道是默认构造函数
但a(int aa=0){};这种写法我觉得不直观,有时候概念不清会被误看成带参构造函数,但它功能其实是转变成为了默认构造函数(无参构造函数)
但形式却又是带参构造函数,我记得在范磊老师的书上没有看到过把参数直接初始化为0的例子
而且这么一做即不能定义默认构造函数,同时也不能定义相同类型的带参构造函数了!何苦呢


[ 本帖最后由 xg5699 于 2011-8-18 13:59 编辑 ]

都不结贴我郁闷那!
2011-08-18 13:14
xg5699
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:140
专家分:522
注 册:2011-7-27
收藏
得分:0 
另外创建d1时也屏蔽掉了默认构造函数
用你的方法是屏蔽掉了默认构造函数,但问题是它总是要使用了一个构造函数,不是拖裤子放屁吗


[ 本帖最后由 xg5699 于 2011-8-18 14:15 编辑 ]

都不结贴我郁闷那!
2011-08-18 13:54
jcw08120110
Rank: 8Rank: 8
来 自:南京
等 级:蝙蝠侠
帖 子:272
专家分:742
注 册:2009-6-8
收藏
得分:0 
回复 7楼 xg5699
图片附件: 游客没有浏览图片的权限,请 登录注册

你说总是要用默认构造函数;肯定啊 你要对象就会要用构造函数; 可是为什么要自定义构造函数呢?? 为什么?就是因为默认构造函数不能做到我们想要的 我们想要什么, 我们想在自定义构造函数中给数据成员赋值;不让那些元素指针什么的在游离状态; 那么有了自定义函数 我们 还要再 定义一个默认构造函数 用来防止我上面说的 派生类的默认构造调用基类的默认构造时所出现的问题; 那么就要至少2个构造函数; 在这里我们只要定义一个带构造参数列表的含默认参数的构造函数就能解决问题;那你说究竟是哪个拖裤子放屁呢??

至于你说的问题下面 你自己看; 绝对可以运行
~
图片附件: 游客没有浏览图片的权限,请 登录注册


[ 本帖最后由 jcw08120110 于 2011-8-18 15:32 编辑 ]

君生我未生 我生君以老
2011-08-18 15:17
xg5699
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:140
专家分:522
注 册:2011-7-27
收藏
得分:0 
回复 8楼 jcw08120110
程序代码:
#include<iostream>
using namespace std;
class a
{
private:
    int j;
public:
// a():i(0){};

};
class b:public a
{
private:
    int *i;
public:
    b():i(0){};

};

void main()
{
    b cla;
}
有好的方法应该学习,我没有很明白你所说的
我们想在自定义构造函数中给数据成员赋值;不让那些元素指针什么的在游离状态; 那么有了自定义函数 我们 还要再 定义一个默认构造函数 用来防止我上面说的 派生类的默认构造调用基类的默认构造时所出现的问题;
我用b类自定义的构造函数初始化指针没见我必须要在基类中重新定义一个默认构造函数呀?

   希望你能举个简单的例子演示以下让我多学习学习,麻烦啦~

[ 本帖最后由 xg5699 于 2011-8-18 15:40 编辑 ]

都不结贴我郁闷那!
2011-08-18 15:35
jcw08120110
Rank: 8Rank: 8
来 自:南京
等 级:蝙蝠侠
帖 子:272
专家分:742
注 册:2009-6-8
收藏
得分:0 
回复 9楼 xg5699
很简单的道理  上课时 老师不断教我们 指针定义时最好别放空 游离的指针是罪恶之源;比如我们定义int *p;忘记赋值后面调用到p则会出现错误; 对吧 然后 我自定义了带参的构造函数后;那些指针元素都有一个初始值;至少不再游离了;
然后我们要派生,派生类如果有了带参的构造函数(为什么要定义带默认参数的构造函数,你可能的意思是派生类就是用默认构造函数;不过上面我已经说过了 是为了安全考虑这是编程风格,安全的编程风格)
我用b类自定义的构造函数初始化指针没见我必须要在基类中重新定义一个默认构造函数呀?
我没说要定义默认构造函数; 我的风格是这样 子类和基类中都是带构造参数列表含有默认参数的构造函数
图片附件: 游客没有浏览图片的权限,请 登录注册

君生我未生 我生君以老
2011-08-18 15:56
快速回复:关于继承和派生代码
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.023782 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved