父子间的冲突(四十)-创新互联

    我们学习了继承,那么现在就有一个问题了:子类中是否可以定义父类中的同名成员呢?如果可以,那么将如何区分?如果不可以,为什么呢?我们来用代码说明,看看是否支持

成都创新互联公司是一家集网站建设,化州企业网站建设,化州品牌网站建设,网站定制,化州网站建设报价,网络营销,网络优化,化州网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。
#include 
#include 

using namespace std;

class Parent
{
public:
    int mi;
};

class Child : public Parent
{
public:
    int mi;
};

int main()
{
    Child c;
    
    c.mi = 10;
    
    return 0;
}

        我们在父类 Parent 中定义了一个成员变量 mi,在子类 Child 中也定义了成员变量 mi;那么我们直接对 c.mi 进行赋值操作,看看编译器能否识别?

父子间的冲突(四十)

        经过编译,我们知道了编译器支持这样的写法,也就说,它知道此时我们赋值的是哪个 mi。在 C++ 中,其实子类是可以定义父类中的同名成员的,子类中的成员将隐藏父类中的同名成员。但父类中的同名成员依然存在于子类中,我们通过作用域分辨符(::)来访问父类中的同名成员。下来我们通过编程来看看怎样使用父类中被隐藏的同名成员。

#include 
#include 

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 = 10;
    c.Parent::mi = 100;
    
    cout << "c.mi = " << c.mi << endl;
    cout << "&c.mi = " << &c.mi << endl;
    
    cout << endl;
    
    cout << "c.Parent::mi = " << c.Parent::mi << endl;
    cout << "&c.Parent::mi = " << &c.Parent::mi << endl;
    
    return 0;
}

        我们看到先打印两个类中定义的变量的地址,然后进行赋值,通过再次打印赋值操作的变量的地址来确定我们操作的到底是父类中的成员变量还是子类中的成员变量,编译结果如下

父子间的冲突(四十)

        我们看到 c.mi 的地址和子类中的成变量的地址是一致的,而 c.Parent::mi 的地址和父类中的成员变量的地址是一致的。那么类中的成员函数是否可以进行重载呢?重载函数的本质为多个不同的函数,函数名和参数列表是唯一的标识,函数重载必须发生在同一个作用域中。那么子类中定义的函数是否能重载父类中的同名函数?我们还是以代码为例来进行分析

#include 
#include 

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;
    
};

int main()
{
    Child c;
    
    c.mi = 10;
    c.Parent::mi = 100;
    
    cout << "c.mi = " << c.mi << endl;
    cout << "c.Parent::mi = " << c.Parent::mi << endl;
    
    c.add(1);
    c.add(2, 3);
    
    cout << endl;
    
    cout << "c.mi = " << c.mi << endl;
    cout << "c.Parent::mi = " << c.Parent::mi << endl;
    
    return 0;
}

        我们在父类中定义了两个 add 重载函数,那么我们在 main 函数中去使用,看看它会用在父类还是子类的成员变量中。

父子间的冲突(四十)

        我们看到是父类中的成员变量使用 add 函数了。那么我们在子类中也定义 void add(int a, int b, int c) 函数呢?在 main 函数中添加 c.add(4, 5, 6);我们来看看编译结果

父子间的冲突(四十)

        它报错了,没有可调用的函数,因为在这会发生同名覆盖。由此可见,子类中的函数无法重载父类中的成员函数,子类中的函数将隐藏父类中的同名函数。我们必须得使用作用域分辨符来访问父类中的同名函数,那么在子类中可以定义父类中完全相同的成员函数。我们试着加上作用分辨符(c.Parent::add(1); c.Parent::add(2, 3);),再来编译下看看

父子间的冲突(四十)

        我们看到已经编译通过,并且运行也是我们想要的效果。通过对父子关系的学习,总结如下:1、子类中可以定义父类中的同名成员;2、子类中的成员将隐藏父类中的同名成员;3、子类和父类中的函数不能构成重载关系;4、子类可以定义父类中完全相同的成员函数;5、使用作用域分辨符可以访问父类中的同名成员。

        欢迎大家一起来学习 C++ 语言,可以加我QQ:243343083。

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


文章标题:父子间的冲突(四十)-创新互联
网站路径:http://myzitong.com/article/dcjdoi.html