首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • 基类与派生类的转换问题。 [已结贴,结贴人:cen_jin_long]
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • cen_jin_long
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    • 揭帖率:
    发表于:2008-06-24 18:17:47 楼主
    C/C++ code
    class A { public: A() { a = 1; } int a; void OutPut() { cout<<"A"<<a<<endl; } }; class B : public A { public: B() { a = 2; } void OutPut() { cout<<"B"<<a<<endl; } }; void main() { A a; B b; a.OutPut();//结果为1 a = b; a.OutPut();//结果为2 A a1; B b1; A &r = a1;//引用变量r是a1的别名 r.OutPut();//结果为1 r = b1;//这句怎么理解? r.OutPut();//结果为2 }
    20  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • cen_jin_long
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-06-24 18:20:141楼 得分:0
    解释为这段“此时r并不是b1的别名,也不与b1共享同一段存储单元。它只是b1中基类部分的别名,r与b1中基类部分共享同一段存储单元,r与b1具有相同的起始地址。”

    不是很明白。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • heguodong
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-06-24 18:22:052楼 得分:2
    引用楼主 cen_jin_long 的帖子:
    C/C++ code
    class A
    {
    public:
        A()
        {
            a = 1;
        }
        int a;
        void OutPut()
        {
            cout < <"A" < <a < <endl;
        }
    };

    class B : public A
    {
    public:
        B()
        {
            a = 2;
        }
        void OutPut()
        {
            cout < <"B" < <a < <endl;
        }
    };

    void main()
    {
        A a;
        B b;  --->这时候b.a=2,调用的是B的构造
        a.OutPut();//结果为1
        a = b;
        a.OutPut();//结果为2-->>掉用的是A的OutPut,但是其值是2,没错,输出是A2

        A…

    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • xkyx_cn
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    • 2

    发表于:2008-06-24 18:43:203楼 得分:2
    C/C++ code
    void main() { A a; B b; a.OutPut();//结果为1 a = b; a.OutPut();//结果为2 A a1; B b1; A &r = a1;//引用变量r是a1的别名 r.OutPut();//结果为1 cout<< (int*)&a1 <<endl; cout<< (int*)&r <<endl; // a1与r 地址值相同 r = b1; // 注意,此处会改变a1的a r.OutPut();// 结果为A2 a1.OutPut();// 此处结果为A2 }
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • JavaConquer
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-06-24 19:21:204楼 得分:2
    都是默认的复制构造函数在捣乱啊
    当r=b1
      a = b;
    时被调用啊

    int main(int argc,char **argv)
    {
        A a;
        B b;
        a.OutPut();//结果为1
        a = b;
        a.OutPut();//结果为2
       
        A a1;
        B b1;
        A &r = a1;//引用变量r是a1的别名
        r.OutPut();//结果为1
        r = b1;   
        r.OutPut();// 结果为A2
        a1.OutPut();// 此处结果为A2
            b1.a=5;
    b1.b=5;
        r.OutPut();
        b1.OutPut();;//此处结果为5
        return 1;
    }

    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • k2eats
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-06-24 19:47:545楼 得分:2
    引用楼主 cen_jin_long 的帖子:
    C/C++ code
    class A
    {
    public:
        A()
        {
            a = 1;
        }
        int a;
        void OutPut()
        {
            cout < <"A" < <a < <endl;
        }
    };

    class B : public A
    {
    public:
        B()
        {
            a = 2;
        }
        void OutPut()
        {
            cout < <"B" < <a < <endl;
        }
    };

    void main()
    {
        A a;
        B b;
        a.OutPut();//结果为1
        a = b;
        a.OutPut();//结果为2

        A a1;
        B b1;
        A &r = a1;//引用变量r是a1的别名
        r.OutPut();//结果为1

        r = b1;//这句怎么理解?
    // 这样理解, 引用其实就是对象的别名(引用一旦初始化就不能更改引用的对象!!!),
    //  他们是一个对象,  r = b1, 其实就是 a1 = b1;(改变了对象的值) r.output()就是 a1.output()
        r.OutPut();//结果为2
    }
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • wugeyuan
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-06-24 20:29:136楼 得分:2
    继承与派生里最强悍的思想就是动态绑定了~体现在楼主的问题上就是~
    可以用基类类型的指针或引用调用派生类对象~
    编译器在编译阶段不检查指针或引用的类型~而在运行时确定指针或引用的实际类型~即所谓的动态绑定~
    可以用基类类型的指针或引用绑定派生类的基类部分~
    还有什么静态类型动态类型的~坐到电脑前就短路了~
    这个是很复杂的~我也说不好~楼主最好找本面向对象的书好好研究~看看继承情况下的构造析构怎么设计~借口怎么设计比较好~
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • csusuntao
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-06-24 21:36:257楼 得分:2
    其实问题的实质很简单,引用型变量在使用时要初始化,在初始化后会一直指向所引用的变量。
        A a;
        B b;
        a.OutPut();//结果为1
        a = b;
        a.OutPut();//结果为2

        A a1;
        B b1;
        A &r = a1;//引用变量r是a1的别名
        r.OutPut();//结果为1

        r = b1;//这句怎么理解?
        r.OutPut();//结果为2

    在如上代码中,A &r = a1;对引用变量r进行初始化。
    r = b1; 只不过是对r所引用的变量进行复制。
    至于具体如何拷贝数据,要参考基类和子类的拷贝关系。这点不是这个问题的本质所在。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • ttkk_2007
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-06-24 21:43:428楼 得分:2
    A a1;
        B b1;
        A &r = a1;//引用变量r是a1的别名
        r.OutPut();//结果为1

        r = b1;//这句怎么理解?
        r.OutPut();//结果为2
    =================================
    引用一旦被绑定后,就不能再改变,也就是这里的r一旦成为了a1的别名,那她一直就代表a1,不会在代表别的
    r = b1;不代表r又成为b1的别名,这里相当于a1 = b1;所以他和上面的结果是一样的
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • zwind_fancy
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-06-24 23:43:319楼 得分:2
    r的内存模型既是a1的,对r操作即是对a1操作
    所以     
      A &r = a1;//引用变量r是a1的别名
        r = b1; 这句与 a1 = b1; 是等价的
       
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • fish6344
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-06-25 00:29:3110楼 得分:2
    楼上的说:"引用一旦被绑定后,就不能再改变",这不是真的,请看如下程序:

    void main()
    {
        long a = 1;
        long b = 2;
        long c = 3;
        long& _rlong = a;//引用到a!

        cout < < "_rlong引用到: " < < _rlong < < endl;

        _rlong = b;//修改引用到b!
        cout < < "_rlong引用到: " < < _rlong < < endl;

        _rlong = c;//修改引用到c;
        cout < < "_rlong引用到: " < < _rlong < < endl;

        _PAUSE;
    }

    输出:

    _rlong引用到: 1
    _rlong引用到: 2
    _rlong引用到: 3

    上述程序行为良好,经dev_gcc4、VC7.1及BC6.0编译器编译执行均有一致性良好的行为.

    再请楼主允许我注释你的程序:

    void main()
    {
        A a;
        B b;
        a.OutPut();//结果为1
    /*
      如下从B类型对象到A类型的赋值行为,是C风格的隐式强制类型转换(从派生类到基类的),对于本类而言,因其类体糸只有一个数据成员(int)a,因而这种转换并未有不良行为,但如果派生类含有另外的数据成员,将发生对象的切割,即赋值后的a只有A类的数据成员,B类的数据成员则被切割掉,则就导致了非预期的行为发生!(可参《深度探索C++对象模型》 第3章数据语意学)
    */
        a = b;
        a.OutPut();//结果为2

        A a1;
        B b1;
        A &r = a1;//引用变量r是a1的别名
        r.OutPut();//结果为1

        r = b1;//这句怎么理解?
    /*
        如上语句是非常自然的,C++语言为支持运行时多态本身就支持从派生类的引用或指针到基类的引用或指针的转换!
        如上只不过就是从b1(派生类对象之引用,引用可以认同为其所引用的对象)至A类引用(基类之引用)的转换。
    */
        r.OutPut();//结果为2 <---这正是一个基类之引用引用到一个派生类对象而展现出多态行为!
    }


    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • xkyx_cn
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    • 2

    发表于:2008-06-25 08:41:3511楼 得分:0
    今天才看到lz的基类没有虚函数,并非多态类

    C/C++ code
    void main() { A a; B b; a.OutPut();//结果为1 a = b; a.OutPut();//结果为2 A a1; B b1; A &r = a1;//引用变量r是a1的别名 r.OutPut();//结果为1 r = b1; // 此处要把B类型的对象b1切割为A类型,并且实际上改变的是a1,因为r是a1的引用 r.OutPut(); }

    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • lijing7169
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-06-25 08:50:1912楼 得分:1
      A &r = a1;//引用变量r是a1的别名
        r.OutPut();//结果为1

        r = b1; // 可以这样理解 基类的指针可以指向其派生类 
                  // r a1 有相同的其始地址  这里也就相当与 a1=b1的效果
        r.OutPut();
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • fish6344
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-06-25 10:02:5013楼 得分:0
    楼主的类体糸中的确没有声明virtual函数,但这并不影响语言支持的从派生类引用或指针到基类引用或指针的转换!换言之如下语句,仍获得了这种支持:

    A &r = a1;//引用变量r是a1的别名

    r = b1; //Ok!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • heguodong
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-06-25 10:06:0414楼 得分:0
    这里并没有多态一说,很简单的就是对象的a成员的值是2
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • uurabit
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-06-25 10:20:4915楼 得分:1
    对阿  结果是给a1付知  建议你 看看引用
    修改 删除 举报 引用 回复

    网站简介广告服务网站地图帮助联系方式诚聘英才English 问题报告
    北京创新乐知广告有限公司 版权所有 京 ICP 证 070598 号
    世纪乐知(北京)网络技术有限公司 提供技术支持
    Copyright © 2000-2008, CSDN.NET, All Rights Reserved