zoukankan      html  css  js  c++  java
  • 34 父子间的冲突

    1 问题

    • 子类中是否可以定义父类中的同名成员?如果可以,如何区分?如果不可以,为什么?

    • 示例1:同名成员变量

      • Demo

        #include <iostream>
        #include <string>
        
        using namespace std;
        
        class Parent
        {
        public:
            int mi;
        };
        
        class Child : public Parent
        {
        public:
            int mi;
        };
        
        int main()
        {
            Child c;
            
            c.mi = 100;    // mi 究竟是子类自定义的,还是从父类继承得到的?
            
            return 0;
        }
        
      • 编译通过:说明子类中可以定义父类中的同名成员

    2 父子间的冲突——同名覆盖

    • 子类可以定义父类中的同名成员

    • 子类中的成员将隐藏父类中的同名成员

    • 父类中的同名成员依然存在于子类中

    • 通过作用域分辨符(::) 访问父类中的同名成员(类似于不同的命名空间 namespace 可以定义同名的变量)

      Child c;
      c.mi = 100;  //子类中的mi
      c.Parent::mi = 1000;  //父类中的mi
      
    • 示例2:同名成员变量

      • Demo

        #include <iostream>
        #include <string>
        
        using namespace std;
        
        class Parent
        {
        public:
            int mi;
            
            Parent()
            {
                cout << "Parent() : " << "&mi = " << &mi << endl;
            }
        };
        
        class Child : public Parent
        {
        public:
            int mi;
            
            Child()
            {
                cout << "Child() : " << "&mi = " << &mi << endl;
            }
        };
        
        int main()
        {
            Child c;
            
            c.mi = 100;    
            
            c.Parent::mi = 1000;
            
            cout << "&c.mi = " << &c.mi << endl;
            cout << "c.mi = " << c.mi << endl;
            
            cout << "&c.Parent::mi = " << &c.Parent::mi << endl;
            cout << "c.Parent::mi = " << c.Parent::mi << endl;
            
            return 0;
        }
        
      • 编译运行

        Parent() : &mi = 0xbfb43a08
        Child() : &mi = 0xbfb43a0c
        &c.mi = 0xbfb43a0c
        c.mi = 100
        &c.Parent::mi = 0xbfb43a08
        c.Parent::mi = 1000
        

    3 重载与父子间的冲突

    • 类的成员函数可以重载

      • 1.重载函数的本质为多个不同的函数
      • 2.函数名和参数列表是唯一的标识
      • 3.函数重载必须发生在同一个作用域中
    • 问题:子类中定义的函数是否能重载父类中的同名函数

      • 不能,同属于不同的作用域,不能重载
    • 示例3:父子间的函数重载

      • Demo1

        #include <iostream>
        #include <string>
        
        using namespace std;
        
        class Parent
        {
        public:
            int mi;
            
            void add(int v)
            {
                mi += v;
            }
            
            void add(int a, int b)
            {
                mi += (a + b);
            }
        };
        
        class Child : public Parent
        {
        public:
            int mi;
            
            //“所谓的”重载
            void add(int x, int y, int z)
            {
                mi += (x + y + z);
            }
        };
        
        int main()
        {
            Child c;
            
            c.mi = 100;    
            
            c.Parent::mi = 1000;
            
            cout << "c.mi = " << c.mi << endl;
            
            cout << "c.Parent::mi = " << c.Parent::mi << endl;
            
            c.add(1);
            c.add(2, 3);
            c.add(4,5,6);
            
            cout << "c.mi = " << c.mi << endl;
            
            cout << "c.Parent::mi = " << c.Parent::mi << endl;
            
            return 0;
        }
        
      • 编译:父类的同名函数被覆,只能调用子类中的函数 void add(int x, int y, int z)

        test.cpp: In function ‘int main()’:
        test.cpp:46: error: no matching function for call to ‘Child::add(int)’
        test.cpp:28: note: candidates are: void Child::add(int, int, int)
        test.cpp:47: error: no matching function for call to ‘Child::add(int, int)’
        test.cpp:28: note: candidates are: void Child::add(int, int, int)
        
    • 重载与父子间的冲突

      • 子类中的函数将隐藏父类的同名函数

      • 子类无法重载父类中的成员函数

      • 使用作用域分辨符访问父类中的同名函数

        int main()
        {
            Child c;
            
            c.mi = 100;    
            
            c.Parent::mi = 1000;
            
            cout << "c.mi = " << c.mi << endl;
            
            cout << "c.Parent::mi = " << c.Parent::mi << endl;
            
            c.Parent::add(1);
            c.Parent::add(2, 3);
            c.add(4,5,6);
            
            cout << "c.mi = " << c.mi << endl;
            
            cout << "c.Parent::mi = " << c.Parent::mi << endl;
            
            return 0;
        }
        
        //输出
        c.mi = 100
        c.Parent::mi = 1000
        c.mi = 115
        c.Parent::mi = 1006
        
      • 子类可以定义父类中完全相同的成员函数:通过再次定义与父类的相同的函数,避免被子类的同名函数隐藏

        #include <iostream>
        #include <string>
        
        using namespace std;
        
        class Parent
        {
        public:
            int mi;
            
            void add(int v)
            {
                mi += v;
            }
            
            void add(int a, int b)
            {
                mi += (a + b);
            }
        };
        
        class Child : public Parent
        {
        public:
            int mi;
            
            //再次定义相同的函数,避免父类的同名函数被隐藏
            void add(int v)
            {
                mi += v;
            }
            
            //再次定义相同的函数,避免父类的同名函数被隐藏
            void add(int a, int b)
            {
                mi += (a + b);
            }
            
            void add(int x, int y, int z)
            {
                mi += (x + y + z);
            }
        };
        
        int main()
        {
            Child c;
            
            c.mi = 100;    
            
            c.Parent::mi = 1000;
            
            cout << "c.mi = " << c.mi << endl;
            
            cout << "c.Parent::mi = " << c.Parent::mi << endl;
            
            c.add(1);
            c.add(2, 3);
            c.add(4, 5, 6);
            
            cout << "c.mi = " << c.mi << endl;
            
            cout << "c.Parent::mi = " << c.Parent::mi << endl;
            
            return 0;
        }
        
        
        //输出
        c.mi = 100
        c.Parent::mi = 1000
        c.mi = 121
        c.Parent::mi = 1000
        
  • 相关阅读:
    Notes for Advanced Linux Programming 2. Writing Good GNU/Linux Software
    GIT 子模块温习
    Memcached 源码分析——从 main 函数说起
    Zookeeper 初体验之——JAVA实例
    如何使用 indent 美化你的代码
    PGF/TIKZ 资源汇总
    Zookeeper 进阶之——Zookeeper编程示例(如何使用Zookeeper实现屏障Barriers和队列Queues)
    Zookeeper 进阶之——典型应用场景(二)
    如何将 Linux 内核实现的红黑树 rbtree 运用到你的 C 程序中?
    三行代码实现C语言单元测试框架
  • 原文地址:https://www.cnblogs.com/bky-hbq/p/13903906.html
Copyright © 2011-2022 走看看