Chinaunix首页 | 论坛 | 博客
  • 博客访问: 300258
  • 博文数量: 148
  • 博客积分: 4365
  • 博客等级: 上校
  • 技术积分: 1566
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-05 21:38
文章分类
文章存档

2014年(2)

2013年(45)

2012年(18)

2011年(1)

2009年(54)

2008年(28)

我的朋友

分类: C/C++

2008-10-06 19:06:40

基类与派生类之间的转换
前面我们看到动态绑定发生的两个条件:1.被调用的函数为虚函数。2.通过指向基类的引用或指针调用。
我们是可以让基类的引用或指针指向派生类的,因为派生类都含有其基类作为其的一部分,当有这样的函数形参时,编译器会默认将参数作为基类型,这样是安全的,运行时再根据实参动态绑定。
基类型的引用或指针是静态类型(static type),编译时确定;而它们所指向的内容是动态类型(dynamic type),运行时确定。这也是C++中实现多态的关键。
如果确定是想要调用派生类中基类版本的函数,可以通过作用域符::

base *p=&derived;
p->base::func();

这样调用将在编译时确定。
只有成员函数中的代码才应该使用这样的方式。

虚函数也可以拥有默认参数,如果通过动态绑定方式调用这个虚函数时(通过基类的引用或指针),默认参数的值就是基类中定义的,与动态绑定无关,但其它部分是动态绑定的。

class base{
public:
    int pub;
    virtual void func(int );
};
void base::func(int i=1){
    cout<<"i= "<<i<<" in base"<<endl;
}

class derived :public base{
public:
    void func(int i=2){
        cout<<"i= "<<i<<" in derived"<<endl;
    }
};


void f2(base& ref_b){
    ref_b.func();
}

int main(void) {
    derived obj1;
    f2(obj1);
    cout<<"end in main\n";
    return EXIT_SUCCESS;
}

运行结果

i= 1 in derived
end in main

看到默认参数i的值是基类中确定的1,但其后的输出确是 in derived,动态绑定。
所以虚函数尽量避免使用默认参数。

继承方式有三种,公有,保护,私有继承。
基类中的私有成员只有基类的私有成员和它的友元能够访问,哪种派生后的派生类都不能访问。
公有继承中,基类中的成员继续保持它们各自的访问限制。
保护继承中,基类的成员都变为派生类的保护成员。
私有继承中,基类全部成员都变为派生类的私有成员。
实际程序中绝大部分派生都是公有的。

基类的私有成员派生后派生类不能访问,还是就没有继承呢

class base{
public:
    
int i;
private:
    
int a;
};
class derived :private base{
public:
};
int main(void) {
    derived obj_d
;
    obj_d
.a=1;
    obj_d
.i=2;
}

派生类私有派生,编译错误
`int base::a' is private
`int base::i' is inaccessible
如果去掉现main函数中内容,只在其中输出 sizeof 基类和派生类的值,都是8,说明私有成员也继承了,只是
不能访问。

当进行保护或私有派生时,如果我们还想使基类的某个公有成员保持公有的属性,怎么办,使用using语句。

class base{
public:
    int i;
private:
    int a;
};
class derived :private base{
public:

    using base::i;
};
int main(void) {
    derived obj_d;
    obj_d.a=1;
    obj_d.i=2;
}

编译时只会在obj_d.a=1;这里报错,`int base::a' is private。
using语句只能用于保持(不能放宽)数据成员的原属性,原来的成员在基类是公有的,在派生类中,using语句也得在公有部分出现。

友元与继承
基类的友元可以访问其保护成员和私有成员,但是友元关系是不能随派生让派生类继承的。

静态成员
基类中有静态成员,则即使经过N次派生后,在整个的派生体系中也只有这一个静态成员。

class base{
public:
    static int i;
private:
    int a;
};

class derived1 :public base{
public:

};

class derived2 :public base{
public:

};
int base::i=0;
int main(void) {
derived1::i=1;
derived2::i=2;
cout<<"base::i= "<<base::i<<endl;
}

结果为 base::i= 2

阅读(756) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~