您的位置:首页 > 编程语言 > C语言/C++

c++派生类转换为基类与public、protected、private继承的关系

2013-11-15 10:34 537 查看
在《c++primer第四版中文》中p579,对“派生类到基类转换的可访问性”讲的比较模糊,于是用visual studio 2008花了四个小时把大部分能想到的情况都试验了一下,得出如下结果。

这里的后代类指的是由基类派生的派生类派生出来的类。也就是类层次中的第三层。

当为public派生时:

派生类定义体中:

构造函数中:

构造函数体中不能定义派生类对象(虽然能通过编译,但运行中会出现错误),但可以定义基类对象、指针和引用。

可以定义派生类和基类的指针及引用。既然不能定义派生类对象,就无法初始化引用(引用必须在定义时初始化),也就无法让派生类的引用对基类引用初始化或赋值了。并且,派生类的指针也不能初始化,只能赋空值,这样派生类的指针就可以对基类指针初始化或赋值。但这么做似乎没有什么意义。

复制控制成员:

复制函数:

可以定义派生类和基类的对象、指针、引用。

除了派生类复制函数的功能不能使用外(即不能用派生类对象对派生类对象进行初始化),其它和用户代码中一样。

赋值函数:

可以定义派生类和基类的对象、指针、引用。

除了派生类赋值函数的功能不能使用外(即不能用派生类对象对派生类对象进行赋值),其它和用户代码中一样。

析构函数:

构造函数体中不能定义派生类对象(虽然能通过编译,但运行中会出现错误),但可以定义基类对象。

其它函数体中:

可以定义派生类和基类的对象、指针、引用。

情况和在派生类用户代码中一样。

其它位置:

只能定义派生类指针,能定义基类对象、指针和引用。

后代类定义体中:

所有成员函数中:

可以定义派生类和基类的对象、指针、引用。

情况和在派生类用户代码中一样。

其它位置:

可以定义派生类和基类的对象、指针、引用。

后代类的用户代码:

后代类对象可以对基类对象进行初始化和赋值;

后代类对象的地址可以对基类的指针进行初始化和赋值;

后代类的对象和引用可以对基类的引用进行初始化和赋值;

派生类用户代码中:

派生类对象可以对基类对象进行初始化和赋值;

派生类对象的地址可以对基类的指针进行初始化和赋值;

派生类的对象和引用可以对基类的引用进行初始化和赋值;

当为protected派生时:

派生类定义体中:

由于派生列表中的访问标号只对用户代码和后代派生类有影响,对派生类访问基类成员没有影响,所以,此处情况应该同上。

后代类定义体中:

派生类可以转换为基类;

后代类可以转换为基类(注意:在构造函数和复制控制成员中的限制和派生类中一样);

派生类用户代码中:

派生类无法转换为基类;

后代类无法转换为基类;

当为private派生时:

派生类定义体中:

由于派生列表中的访问标号只对用户代码和后代派生类有影响,对派生类访问基类成员没有影响,所以,此处情况应该同上。

后代类定义体中:

派生类无法转换为基类;

后代类无法转换为基类;

用户代码中:

派生类无法转换为基类;

后代类无法转换为基类;

下面是用来做试验的类层次,只举出几个例子。实际在试验过程中,每次只试验一种情况,试验完毕马上擦掉,以免影响接下来的试验结果。

class A

{

public:

A(const int &ru = 0)

: base(ru) {}

A(const A &pp)

: base(pp.base) { A w; A s(w); } //试验复制控制函数里的情况,就是在这里面加定义和转换代码,这个

virtual ~A() {} //示例在用户使用此函数时会出错。例在main()中执行 A a; A b(a)。

private:

int base;

protected:

};

class B :private A

{

public:

B(const int &ru = 0, const int &ru2 = 0)

: A(ru), bulk(ru2) { B a; } //试验构造函数里的情况,在这里加代码。这个示例,当用户在main()中定义B a;时就会出错。

~B() { B b; } //试验析构函数里的情况,在这里加代码。这个示例,在发生此类型的析构时就会出错。

private:

int bulk;

protected:

};

class C : public B

{

public:

C(const int &ru = 0, const int &ru2 = 0, const int &ru3 = 0)

: B(ru, ru2), bulk2(ru3) {}

void uuuu() { A a; B b; C c; a = b; a = c; } //试验其它函数里面的情况,在这里面加定义的转换代码,此示例可行,不会出现错误。

~C() {}

private:

int bulk2;

protected:

};

总结:在可以访问到基类public成员的地方,可以进行派生类到基类的转换。

在用visual studio 2008试验上述规则时,发现在类定义体中,构造函数里面不能定义本身类的对象,否则在用户代码中使用时,运行会出现错误;析构函数里面也不能定义本身类对象,运行时会出现错误;在复制函数里可以定义本身类对象,在这个函数内部不能使用本身的复制功能,否则运行时同样会出错;在赋值函数里也可以定义本身类对象,在这个函数里面也不能使用本身类的赋值功能,否则还是会出错;

在其它成员函数里面可以定义本身类的对象,也能使用复制控制功能。

在类定义体内,不属于成员函数的范围,只能定义本身类的指针或引用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: