chapter 17: 类继承和子类型 心得
2006-01-06 00:22
155 查看
chapter 17: 类继承和子类型
现在工作中也用到了比较恶心的方法:
例如:
void Equal()
{
switch(class_type)
{
case Student:
Student * Stu =static_cast<Student*> (p);
Stu->Equal();
break;
case Teacher:
Teacher * Tea = static_cast<Teacher*> (p);
Tea->Equal();
break;
default:
error;
};
};
一个对象的大小是由该类(包含基类和子类)的非静态数据成员决定的。
#include <iostream>
using namespace std;
class base
{
public:
int a;
static int s ;
};
int base::s = 0;
int main()
{
cout << sizeof(base)<<endl; // -- 4
base b;
cout << sizoef(b)<<endl; // --4
return 0;
};
如果在子类中设置了和基类一样的数据或者方法成员,则基类的数据或者方法成员会被隐藏。如果确实需要访问基类的数据或者方法成员,则需要使用类域操作符::。
如果不被隐藏,那么如果使用者可能在基类和子类中都生成原型一样的函数,导致重复定义。而现在则是隐藏基类的成员。
p740:定义的基类指针访问的一些限定:1基类指针只能访问在该类中被声明或继承的数据成员和成员函数,包括虚拟成员函数,而与它可能指向的实际对象无关。
P742: 友元关系是没有继承的。
例如:
class base
{
public:
friend class delivier;
};
class Sam : public delivier
{
};
这里Sam就不能访问base的非共有成员。
友元关系必须显示继承。
P744:
构造函数的调用顺序总是如下:
1 基类构造函数.如果有多个基类,则构造函数的调用顺序是某类在类派生表中出现的
顺序,而不是它们在成员初始化表中的顺序.
2 成员类对象构造函数.如果有多个成员类对象,则构造函数的调用顺序是对象在类中
被声明的顺序,而不是它们出现在成员初始化表中的顺序.
3 派生类构造函数.
P749:
一般情况下如此,析构函数与上相反。
例外情况:
class base
{
public:
base(){};
~base(){};
};
class deliver: public base
{
public:
deliver() {};
~deliver() {};
};
int main()
{
base* p = new deliver();
delete p; //这里只会调用base的析构函数,如果把deliver声明为虚析构函数,则是先deliver的析构函数再调用base的析构
return 1;
};
P760:虚拟函数和缺省实参
缺省实参的确定是在编译时刻根据被调用函数的对象的类型决定,而不是运行时绝定。
可以认为编译时先根据类型,填充缺省参数,再运行时判断实际调用类。
换一句话: 虚拟机制不支持根据被调用函数的实际实例而决定缺省参数。
。。。。
。。。。
。。。。
另外知道了struct的初始化方法,比较ex(BC,g++都不行,):
struct student
{
int id;
int age;
};
struct student stu =
{
.id = 0;
.age = 0;
};
现在工作中也用到了比较恶心的方法:
例如:
void Equal()
{
switch(class_type)
{
case Student:
Student * Stu =static_cast<Student*> (p);
Stu->Equal();
break;
case Teacher:
Teacher * Tea = static_cast<Teacher*> (p);
Tea->Equal();
break;
default:
error;
};
};
一个对象的大小是由该类(包含基类和子类)的非静态数据成员决定的。
#include <iostream>
using namespace std;
class base
{
public:
int a;
static int s ;
};
int base::s = 0;
int main()
{
cout << sizeof(base)<<endl; // -- 4
base b;
cout << sizoef(b)<<endl; // --4
return 0;
};
如果在子类中设置了和基类一样的数据或者方法成员,则基类的数据或者方法成员会被隐藏。如果确实需要访问基类的数据或者方法成员,则需要使用类域操作符::。
如果不被隐藏,那么如果使用者可能在基类和子类中都生成原型一样的函数,导致重复定义。而现在则是隐藏基类的成员。
p740:定义的基类指针访问的一些限定:1基类指针只能访问在该类中被声明或继承的数据成员和成员函数,包括虚拟成员函数,而与它可能指向的实际对象无关。
P742: 友元关系是没有继承的。
例如:
class base
{
public:
friend class delivier;
};
class Sam : public delivier
{
};
这里Sam就不能访问base的非共有成员。
友元关系必须显示继承。
P744:
构造函数的调用顺序总是如下:
1 基类构造函数.如果有多个基类,则构造函数的调用顺序是某类在类派生表中出现的
顺序,而不是它们在成员初始化表中的顺序.
2 成员类对象构造函数.如果有多个成员类对象,则构造函数的调用顺序是对象在类中
被声明的顺序,而不是它们出现在成员初始化表中的顺序.
3 派生类构造函数.
P749:
一般情况下如此,析构函数与上相反。
例外情况:
class base
{
public:
base(){};
~base(){};
};
class deliver: public base
{
public:
deliver() {};
~deliver() {};
};
int main()
{
base* p = new deliver();
delete p; //这里只会调用base的析构函数,如果把deliver声明为虚析构函数,则是先deliver的析构函数再调用base的析构
return 1;
};
P760:虚拟函数和缺省实参
缺省实参的确定是在编译时刻根据被调用函数的对象的类型决定,而不是运行时绝定。
可以认为编译时先根据类型,填充缺省参数,再运行时判断实际调用类。
换一句话: 虚拟机制不支持根据被调用函数的实际实例而决定缺省参数。
。。。。
。。。。
。。。。
另外知道了struct的初始化方法,比较ex(BC,g++都不行,):
struct student
{
int id;
int age;
};
struct student stu =
{
.id = 0;
.age = 0;
};
相关文章推荐
- 学习笔记: Chapter 17 Inheritance 继承
- 2017_7_17元素类型与转换 导航条心得
- 不继承 IEnumerable 或 IQueryable 的类型怎么使用 LINQ 查询
- Java中使用Hibernate存储Date类型及Boolean类型到Orcale数据库中的心得
- B继承自A,A指针无法隐式转换为B指针,函数参数只管指针类型,与实际指向对象无关
- [Javascript 高级程序设计]学习心得记录4 基本包装类型
- mysql varchar类型使用心得
- 继承和虚函数、虚基类的类型大小的比较
- 每日学习心得:Js基本数据类型常用方法扩展
- 《CLR Via C#》 学习心得之三 基元类型、引用类型和值类型
- Spring学习心得(11)-- spring配置文件的继承和抽象属性
- C语言中有关数据类型的心得
- Q_DECLARE_METATYPE(继承QObject的类都已经自动注册),注册后的类型可以作为QVariant的自定义类型
- Linux开发心得总结17 - Linux程序数据段分布分析
- [翻译]并非一切类型都继承源自object
- [Unity&C#&接口]通过接口调用不同类型 物体 的继承了接口的组件
- Java中的集合类型的继承关系图
- 注册插件:违反了继承安全性规则,派生类型必须与基类型的安全性匹配或低于比基类型的安全可访问性低
- Effective JavaScript Item 40 避免继承标准类型
- 继承方法计算不同类型工资