当前位置: 首页 > news >正文

建网站个人主机做服务器山东网站建设哪家好

建网站个人主机做服务器,山东网站建设哪家好,龙岗做网站公司哪家好,安远县城乡规划建设局网站在之前学习学习C类和对象时我们就初步了解到了C当中有三大特性#xff0c;分别是封装、继承、多态#xff0c;通过之前的学习我们已经了解了C的封装特性#xff0c;那么接下来我们将继续学习另外的两大特性#xff0c;在此将分为两个章节来分别讲解继承和多态。本篇就先来学…在之前学习学习C类和对象时我们就初步了解到了C当中有三大特性分别是封装、继承、多态通过之前的学习我们已经了解了C的封装特性那么接下来我们将继续学习另外的两大特性在此将分为两个章节来分别讲解继承和多态。本篇就先来学习继承的相关概念和性质一起加油吧 1.继承的概念和定义 1.继承的概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段它允许我们在保持原有类特性的基础上进行扩展增加方法(成员函数)和属性(成员变量)这样产生新的类称派类。继承呈现了面向对象程序设计的层次结构体现了由简单到复杂的认知过程。以前我们接触的函数层次的复用继承是类设计层次的复用。 接下来我们就通过以上的示例来初步了解继承的优势是什么 #includeiostreamusing namespace std;class Student{public:// 进⼊校园/图书馆/实验室刷⼆维码等⾝份认证void identity(){// ...}// 学习void study(){// ...}protected:string _name peter; // 姓名string _address;// 地址string _tel;// 电话int _age 18;// 年龄int _stuid;// 学号};class Teacher{public:// 进⼊校园/图书馆/实验室刷⼆维码等⾝份认证void identity(){// ...}// 授课void teaching(){//...}protected:string _name 张三;// 姓名int _age 18;// 年龄string _address;// 地址string _tel;// 电话string _title;// 职称};int main(){return 0;}在以上示例当中下面我们看到没有继承之前我们以上设计了两个类Student和TeacherStudent和Teacher都有姓名/地址/电话/年龄等成员变量都有identity身份认证的成员函数设计到两个类面就是冗余的。当然他们也有一些不同的成员变量和函数比如老师独有成员变量是职称学生的独有成员变量是学号学生的独有成员函数是学习老师的独有成员函数是授课。 其实在此以上的代码当中就很适合使用继承来实现实现代码如下所示 #includeiostreamusing namespace std;class Person { public:// 进⼊校园/图书馆/实验室刷⼆维码等⾝份认证void identity(){cout void identity() _name endl;} protected:string _name 张三; // 姓名string _address;// 地址string _tel;// 电话int _age 18;// 年龄 };class Student : public Person { public:// 学习void study(){// ...} protected:int _stuid;// 学号 };class Teacher: public Person { public:// 授课void teaching(){//...} protected:string _title;// 职称};int main() {Student s;Teacher t;s.identity();t.identity();return 0; }对于以上的代码你可能会无法理解为什么以上的Student和Teacher类的结构在类的定义之后要加上:public Person那么接下来我们就来了解继承的定义 1.2 继承的定义 1.2.1 定义格式 下面我们看到Person是基类也称作父类。Student是派生类也称作子类。(因为翻译的原因所以既叫基类/派生类也叫父类/子类) 以下是使用继承时的类形式 因此在以上的示例当中Person就是基类Student和Teacher就都是派生类 1.2.2 继承基类成员访问方式的变化 在此在之前C类和对象章节我们就已经了解过了在类当中的访问限定符有三种public——公有、private——私有、protected——保护不过在之前我们是简单的认为public和protected是一样的但学习到了继承该章节之后就不能这样简单的认为了接下来我们就来详细讲解继承当中继承基类派生类当中成员访问权限的变化 在此先要了解的是基类的继承方式有三种并且派生类的访问限定符也有三种 接下来来看以下的表格 类成员/继承方式public继承protected继承private继承基类的public成员派生类的public成员派生类的protected成员派生类的private成员基类的protected成员派生类的protected成员派生类的protected成员派生类的private成员基类的private成员在派生类当中不可见在派生类当中不可见在派生类当中不可见 通过以上继承基类访问成员方式的变化的表格就可以得出以以下的规律1.基类private成员在派生类中无论以什么方式继承都是不可见的。这里的不可见是指基类的私有成员还是被继承到了派生类对象中但是语法上限制派生类对象不管在类里面还是类外面都不能去访问它。 2. 基类private成员在派生类中是不能被访问如果基类成员不想在类外直接被访问但需要在派生类中能访问就定义为protected。可以看出保护成员限定符是因继承才出现的。 3. 使用关键字class时默认的继承方式是private使用struct时默认的继承方式是public不过最好显示的写出继承方式。 4. 在实际运用中一般使用都是public继承几乎很少使用protetced/private继承也不提倡使用protetced/private继承因为protetced/private继承下来的成员都只能在派⽣类的类里面使用实际中扩展维护性不强。 因此实际上面的表格我们进行⼀下总结会发现重点有以下三条1.基类的私有成员在派生类都是不可见。2.基类的其他成员在派生类的访问方式 Min(成员在基类的访问限定符和继承方式两个当中权限小的那个)在此访问权限大小从大到小为public protected private。3.在实际运用中一般使用都是public继承也就是以上表格的这部分 2. 继承类模板 之前在模拟实现stck当中我们是使用容器适配器的方式来实现其实除了之前的方式之外还可以使用继承类模板来模拟实现stck 以下就是使用继承类模板来模拟实现stack #includeiostream #includevector using namespace std;namespace zhz {//templateclass T//class vector//{};// stack和vector的关系既符合is-a也符合has-atemplateclass Tclass stack : public std::vectorT{public:void push(const T x){// 基类是类模板时需要指定⼀下类域// 否则编译报错:error C3861: “push_back”: 找不到标识符// 因为stackint实例化时也实例化vectorint了// 但是模版是按需实例化push_back等成员函数未实例化所以找不到vectorT::push_back(x);//push_back(x);}void pop(){vectorT::pop_back();}const T top(){return vectorT::back();}bool empty(){return vectorT::empty();}}; } int main() {zhz::stackint st;st.push(1);st.push(2);st.push(3);while (!st.empty()){coutst.top() ;st.pop();} }注以上在继承类模板时要注意的是在派生类当中要调用基类的成员函数时要指明类域否则将会找不到对应的函数编译器会出现报错  在此你可能还会有疑惑是在我们是在实例化出stack的对象之后调用其内部的成员函数那么不应该这时在调用函数时就已经确定要调用的vector的成员函数是指什么类域内吗其实这时由于模板是按需实例化的在对象实例化时其内部的成员函数是没有实例化的而是只有在调用对应的函数才进行实例化的 3.基类和派生类之间的转换 public继承的派生类对象可以赋值给 基类的指针 / 基类的引用。在此这个过程叫做赋值兼容转换这里有个形象的说法叫切片或者切割。寓意把派生类中基类那部分切出来基类指针或引用指向的是派生类中切出来的基类那部分。 该过程可以表示为以下形式 在此要注意基类对象不能赋值给派生类对象。 注基类的指针或者引用可以通过强制类型转换赋值给派生类的指针或者引用。但是必须是基类的指针是指向派生类对象时才是安全的。这里基类如果是多态类型可以使用RTTI(Run-Time Type Information)的dynamic_cast 来进行识别后进行安全转换。ps这个我们后面类型转换章节再 单独专门讲解这里先提⼀下 例如以下示例 #includeiostream using namespace std;class Person { protected:string _name; // 姓名string _sex; // 性别int_age; // 年龄 }; class Student : public Person { public:int _No; // 学号 }; int main() {Student sobj;// 1.派⽣类对象可以赋值给基类的指针/引⽤Person* pp sobj;Person rp sobj;// ⽣类对象可以赋值给基类的对象是通过调⽤后⾯会讲解的基类的拷⻉构造完成的Person pobj sobj;//2.基类对象不能赋值给派⽣类对象这⾥会编译报错sobj pobj;return 0; } 4. 继承中的作用域 4.1 隐藏规则 在继承体系当中其实基类和派生类都有独立的作用域。并且当基类和派生类中有同名成员时派生类的成员将屏蔽对同名成员的直接访问这种情况就叫做隐藏。(在此在隐藏的情况下在派生类成员函数中要访问基类的成员可以使用 基类::基类成员 显示访问) 在此在基类和派生类当中如果是成员函数的隐藏只要函数名相同就构成隐藏并且要是父子类的成员变量相同也叫做隐藏 #includeiostream using namespace std;// Student的_num和Person的_num构成隐藏关系可以看出这样代码虽然能跑但是⾮常容易混淆 class Person { protected:string _name zhz; // 姓名int _num 111;// ⾝份证号void Print(){cout Person: _name _num endl;}}; class Student : public Person { public:void Print(){cout 姓名: _name endl;cout ⾝份证号: Person::_num endl;cout 学号: _num endl;}protected:int _num 999; // 学号 }; int main() {Student s1;//在此调用的就是Student内的Print成员函数s1.Print();return 0; }; 注在实际中在继承体系里面最好不要定义同名的成员这样很容易混淆。 4.2 练习题 在以上我们了解了继承体系当中的作用域以及隐藏规则那么接下来我们就来试着完成以上的练习题来进一步巩固以上的知识 1.A和B类中的两个func构成什么关系 A. 重载 B. 隐藏 C.没关系 #includeiostream using namespace std;class A { public:void fun(){cout func() endl;} }; class B : public A { public:void fun(int i){cout func(int i) i endl;} }; 这以上的两个类A和类B关系是B继承A并且两个类域当中fun函数名相同那么根据隐藏规则就可以得到A和B类中的两个func构成隐藏关系。 因此以上这题选B 2.下面程序的编译运行结果是什么 A. 编译报错 B. 运行报错 C. 正常运行 #includeiostream using namespace std;class A { public:void fun(){cout func() endl;} }; class B : public A { public:void fun(int i){cout func(int i) i endl;} };int main() {B b;b.fun(10);b.fun();return 0; }; 在以上我们知道A和B类中的两个func构成隐藏关系因此在B类型的对象调用fun函数时调用的是B类域内的fun函数又因为B类域内的fun函数是含一个参数的函数那么以上代码中的b.fun()就会编译报错。在此要解决报错就要显示的写出类域;将b.fun()修改为b.A::fun()。 因此以上这题选择A 5.派生类的默认成员函数  在之前类和对象就了6个默认成员函数并且我们了解了这些函数的功能以及要在什么情况下需要显示的写在什么情况下使用编译器自动生成的就可以满足要求 那么在派生类的的默认成员函数和之前普通类有什么区别呢接下来我们就来细致的了解 5.1 构造函数 在之前学习普通类的构造函数我们知道默认规则函数有三种分别是编译器生成的、无参的构造、全缺省的构造。在此编译器编译器自动生成的构造函数对内置类型的处理是不确定的初始化的值是无法确定的而对自定义类型会调用其的默认构造函数并且当内置类型的成员变量无默认构造时就会报错这时就需要相识的在初始化列表显示调用。 在此其实派生类的构造函数依然要遵从以上的规律只不过在派生类构造函数当中多了调用基类的构造函数初始化基类的那一部分成员并且如果基类没有默认的构造函数则必须在派生类构造函数的初始化列表阶段显示调用。 在此派生类对象初始化先调用基类构造再调派生类构造。 例如以下示例 #includeiostream using namespace std;class Person { public:Person(const char* name peter): _name(name){ cout Person() endl;}protected:string _name; // 姓名 };class Student : public Person { public:Student(const char* name, int num): Person(name), _num(num){cout Student() endl;}protected:int _num; //学号 }; 注在此可以将基类看成一个整体和之前内置类型一样都是无默认构造函数时就需要扫显示的调用只不过基类的默认构造调用和内置类型不一样基类是使用 类名(),而内置类型是 对象() 5.2 析构函数 我们知道普通类当中的析构函数是用于完成资源清理的工作并且当中类的成员变量有指向资源时才需要显示的写析构函数否则就不需要析构函数 那么在此在派生类的析构函数和普通类有什么区别呢在此派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员。因为这样才能保证派生类对象先清理派生类成员再清理基类成员的顺序。 因此就可以得出派生类对象析构清理先调用派生类析构再调基类的析构。 在此还要了解的是因为多态中一些场景析构函数需要构成重写重写的条件之一是函数名相同(这个我们多态章节会讲解)。 那么编译器会对析构函数名进行特殊处理处理成destructor()所以基类析构函数不加virtual的情况下派生类析构函数和基类析构函数构成隐藏关系。 例如以下示例  #includeiostream using namespace std;class Person { public:Person(const char* name peter): _name(name){cout Person() endl;}~Person(){cout ~Person() endl;} protected:string _name; // 姓名 };class Student : public Person { public:Student(const char* name, int num): Person(name), _num(num){cout Student() endl;}~Student(){cout ~Student() endl;} protected:int _num; //学号 };int main() {Student s1 (jack, 18);return 0; } 在以上代码中创建了Student的对象之后在此在出main函数之前会先调用Student的析构之后再调用Person的析构 5.3 拷贝构造 之前我们在学习普通类的拷贝构造函数就了解了我们不写编译器自动生成的对内置类型进行的时浅拷贝对自定义类型调用调用其的默认构造在此只有当类当中的有成员变量有指向资源或者是自定义类型的成员变量无默认构造时时需要我们显示的写拷贝构造函数这有成员变量有指向资源时要显示的写是由于要实现的是深拷贝但编译器生成的是浅拷贝这就不符合要求。在此就可以简单的认为当要显示的写析构函数时就需要显示写拷贝构造函数。 那么在此在派生类的拷贝构造函数和普通类有什么区别呢 其实在此其他都和普通类一样只不过派生类多了要对基类成员的处理。派生类的拷贝构造函数必须调用基类的拷贝构造完成基类的拷贝初始化。在此当中基类有默认构造时就不需要显示的调用否则就需要我们显示的调用 例如以下示例 #includeiostream using namespace std;class Person { public:Person(const char* name peter): _name(name){cout Person() endl;}Person(const Person p): _name(p._name){cout Person(const Person p) endl;}~Person(){cout ~Person() endl;} protected:string _name; // 姓名 };class Student : public Person { public:Student(const char* name, int num): Person(name), _num(num){cout Student() endl;}Student(const Student s): Person(s), _num(s._num){cout Student(const Student s) endl;}~Student(){cout ~Student() endl;} protected:int _num; //学号 };int main() {Student s1(jack, 18);return 0; } 在以上代码中在派生类Student的拷贝构造当中在调用基类Person的拷贝构造函数其实是将派生类的引用传给基类的形参在此就运用到之前派生类的对象可以赋值给基类的引用这个过程就实现了切片 5.4 赋值运算符重载 在之前学习普通类的赋值运算符重载我们就了解到了和拷贝构造一样我们不写编译器自动生成的对内置类型进行的时浅拷贝对自定义类型调用调用其的默认构造在此只有当类当中的有成员变量有指向资源或者是自定义类型的成员变量无默认构造时时需要我们显示的写赋值运算符重载函数这有成员变量有指向资源时要显示的写是由于要实现的是深拷贝但编译器生成的是浅拷贝这就不符合要求。在此就可以简单的认为当要显示的写析构函数时就需要显示写赋值运算符重载函数。 例如以下示例   #includeiostream using namespace std;class Person { public:Person(const char* name peter): _name(name){cout Person() endl;}Person(const Person p): _name(p._name){cout Person(const Person p) endl;}Person operator(const Person p){cout Person operator(const Person p) endl;if (this ! p)_name p._name;return *this;}~Person(){cout ~Person() endl;} protected:string _name; // 姓名 };class Student : public Person { public:Student(const char* name, int num): Person(name), _num(num){cout Student() endl;}Student(const Student s): Person(s), _num(s._num){cout Student(const Student s) endl;}Student operator (const Student s){cout Student operator (const Student s) endl;if (this ! s){// 构成隐藏所以需要显⽰调⽤Person::operator (s);_num s._num;}return *this;}~Student(){cout ~Student() endl;} protected:int _num; //学号 };int main() {Student s1(jack, 18);return 0; } 注意要在派生类的赋值运算符重载函数当中调用基类的赋值运算符重载函数由于继承体系下这两个函数构成隐藏因此要在派生类当中调用基类的赋值运算符重载函数就要指明类域   6.不能被继承的类 在此如果我们要实现一个不能被继承的类要怎么做呢以下有两种方法 方法1基类的构造函数私有派生类的构成必须调用基类的构造函数但是基类的构成函数私有化以 后派生类看不生就不能调用了那么派生类就无法实例化出对象。 方法2在C11新增了一个final关键字final修改基类派生生类就不能继承了。 #includeiostream using namespace std;// C11的⽅法 class Base final { public:void func5() { cout Base::func5 endl; } protected:int a 1; private:// C98的⽅法/*Base(){}*/ };class Derive :public Base {void func4() { cout Derive::func4 endl; } protected:int b 2; }; int main() {Base b;Derive d;return 0; } 例如以上代码如果继承Base类时编译器就会出现以下报错 7.继承与友元 友元关系不能继承也就是说基类友元不能访问派⽣类私有和保护成员 。 例如以下示例 #includeiostream using namespace std;class Student; class Person { public:friend void Display(const Person p, const Student s); protected:string _name; // 姓名 }; class Student : public Person { protected:int _stuNum; // 学号 }; void Display(const Person p, const Student s) {cout p._name endl;cout s._stuNum endl; } int main() {Person p;Student s;Display(p, s);return 0; } 以上代码会出现以下的报错 这就是由于基类的友元函数是无法访问派生类的保护成员的要解决以上的报错就要将Display也设置为Student的友元实现代码如下所示 #includeiostream using namespace std;class Student; class Person { public:friend void Display(const Person p, const Student s); protected:string _name; // 姓名 }; class Student : public Person {friend void Display(const Person p, const Student s); protected:int _stuNum; // 学号 };void Display(const Person p, const Student s) {cout p._name endl;cout s._stuNum endl; } int main() {Person p;Student s;Display(p, s);return 0; } 8.继承与静态成员 基类定义了static静态成员则整个继承体系里面只有⼀个这样的成员。无论派生出多少个派生类都只有⼀个static成员实例。 例如以下示例: #includeiostream using namespace std;class Person { public:string _name;static int _count; }; int Person::_count 0; class Student : public Person { protected:int _stuNum; }; int main() {Person p;Student s;// 这⾥的运⾏结果可以看到⾮静态成员_name的地址是不⼀样的// 说明派⽣类继承下来了⽗派⽣类对象各有⼀份cout p._name : p._name endl;cout s._name s._name endl;// 这⾥的运⾏结果可以看到静态成员_count的地址是⼀样的// 说明派⽣类和基类共⽤同⼀份静态成员cout p._count : p._count endl;cout s._count : s._count endl;// 公有的情况下⽗派⽣类指定类域都可以访问静态成员cout Person::_count : Person::_count endl;cout Student::_count : Student::_count endl;return 0; } 在以上代码中Person内的_count成员变量就是静态成员变量因此Person类的对象和Student的对象都是共用这个static成员变量在一个对象当中改变_count的值那么在其他对象的内_count也改变以上代码输出结构如下所示 9.多继承及其菱形继承问题 9.1 继承模型 在继承当中其实大体的是分为单继承和多继承 单继承一个派生类只有⼀个直接基类时称这个继承关系为单继承 多继承⼀个派生类有两个或以上直接基类时称这个继承关系为多继承多继承对象在内存中的模型是先继承的基类在前面后面继承的基类在后面派生类成员在放到最后面。 在多继承当中又会出现一种特殊的情况就是当一个基类有两个派生类之后这两个派生类作为基类又有相同的派生类那么这时就形成菱形继承。 其实菱形继承有很大的问题从下面的对象成员模型构造可以看出菱形继承有数据冗余和⼆义性的问题在Assistant的对象中Person成员会有两份。支持多继承就⼀定会有菱形继承像Java就直接不支持多继承规避掉了这⾥的问题所以实践中我们也是不建议设计出菱形继承这样的模型的。 #includeiostream using namespace std;class Person { public:string _name; // 姓名 };class Student : public Person { protected:int _num; //学号 };class Teacher : public Person { protected:int _id; // 职⼯编号 };class Assistant : public Student, public Teacher { protected:string _majorCourse; // 主修课程 }; int main() {Assistant a;a._name peter;// 需要显⽰指定访问哪个基类的成员可以解决⼆义性问题但是数据冗余问题⽆法解决a.Student::_name xxx;a.Teacher::_name yyy;return 0; } 9.2 虚继承  在学习C之前我们都听很多人说过C相比其他语言语法复杂其实多继承就是⼀个体现。有了多继承就存在菱形继承有了菱形继承就有菱形虚拟继承底层实现就很复杂性能也会有⼀些损失所以最好不要设计出菱形继承。多继承可以认为是C的缺陷之⼀后来的⼀些编程语⾔都没有多继承如Java。 以上我们实现的多继承代码中对“_name”的访问不明确就可以使用虚继承来解决实现代码如下所示 #includeiostream using namespace std;class Person { public:string _name; // 姓名 }; class Student : virtual public Person { protected:int _num; //学号 }; class Teacher : virtual public Person { protected:int _id; // 职⼯编号 }; class Assistant : public Student, public Teacher { protected:string _majorCourse; // 主修课程 }; int main() {Assistant a;a._name peter;return 0; } 注在C中虽然实现了虚继承来解决菱形继承的问题但其实在使用菱形虚拟继承以后无论是使用还是底层都会复杂很多。当然有多继承语法⽀持就⼀定存在会设计出菱形继承像Java是不支持多继承的就避开了菱形继承。 9.3 练习 在了解了多继承的相关概念之后接下来你能来试着回答以下代码中提供的选项哪个是正确的 Ap1 p2 p3 Bp1 p2 p3 Cp1 p3 ! p2 Dp1 ! p2 ! p3 class Base1 { public: int _b1; }; class Base2 { public: int _b2; }; class Derive : public Base1, public Base2 { public: int _d; }; int main() {Derive d;Base1* p1 d;Base2* p2 d;Derive* p3 d;return 0; } 在以上代码中我们将关系图画出来就很好理解了如下所示 在以上代码中是初始化出一个Driver的对象d在这时候就将对象d的指针赋值给Base1类型的指针p1那么这时就会进行赋值兼容转换这时p1就指向对象d所存储的内存空间的首地址。之后再将对象d的指针赋值给Base2类型的指针p2那么这时就也会进行赋值兼容转换这时p1就指向对象d所存储的内存空间的_b2变量的首地址。最后将对象d的指针赋值给Dirver类型的指针p3那么这时拍也是指向d对象的首地址。 通过以上的分析就可以得出p1p3!p2,因此以上选项正确的是C 9.4 IO库中的菱形虚拟继承 其实在IO库当中也是使用菱形继承实现的各个流的关系大致如下所示 10. 继承与组合 在此我们先来了解继承和组合相比各有什么特点呢来看以下的说明 首先是继承和组合两个类之间的关系•public继承是一种is-a的关系。也就是说每个派生类对象都是⼀个基类对象。• 组合是⼀种has-a的关系。假设B组合了A每个B对象中都有⼀个A对象。 接下来是继承和组合两个类之间成员具体的关系• 继承允许你根据基类的实现来定义派生类的实现。这种通过生成派生类的复用通常被称为白箱复用(white-box reuse)。术语“白箱”是相对可视性而言在继承方式中基类的内部细节对派生类可见 。继承⼀定程度破坏了基类的封装基类的改变对派生类有很大的影响。派生类和基类间的依赖关系很强耦合度高。• 对象组合是类继承之外的另⼀种复用选择。新的更复杂的功能可以通过组装或组合对象来获得。对象组合要求被组合的对象具有良好定义的接口。这种复用风格被称为黑箱复用(black-box reuse)因为对象的内部细节是不可见的。对象只以“黑箱”的形式出现。 组合类之间没有很强的依赖关系耦合度低。优先使用对象组合有助于你保持每个类被封装。 无论在实现什么程序时我们实现的代码最好要遵循低耦合、高内聚。因此通过以上的继承和组合的特点就得出在优先使用组合而不是继承。实际尽量多去用组合组合的耦合度低代码维护性好。不过也不太那么绝对类之间的关系就适合继承(is-a)那就用继承另外要实现多态也必须要继承。类之间的关系既适合用继承(is-a)也适合组合(has-a)就用组合。 例如以下示例 // Tire(轮胎)和Car(⻋)更符合has-a的关系 class Tire { protected:string _brand Michelin; // 品牌size_t _size 17;// 尺⼨ }; class Car { protected:string _colour ⽩⾊;// 颜⾊string _num 陕ABIT00;// ⻋牌号Tire _t1;// 轮胎Tire _t2;// 轮胎Tire _t3;// 轮胎Tire _t4;// 轮胎 }; class BMW : public Car { public:void Drive() { cout 好开-操控 endl; } }; // Car和BMW/Benz更符合is-a的关系 class Benz : public Car { public:void Drive() { cout 好坐-舒适 endl; } };templateclass T class vector {}; // stack和vector的关系既符合is-a也符合has-a templateclass T class stack : public vectorT {}; templateclass T class stack { public:vectorT _v; }; int main() {return 0; }
http://www.w-s-a.com/news/805156/

相关文章:

  • dw个人网站主页怎么做天津工程信息建设网
  • 顺义做网站的公司网站页面设计基础教程
  • 安阳哪个公司做网站好企业没有做网站有的坏处
  • 网站开发有必要用php框架wordpress分页导航代码
  • wordpress建站seo鞍山制作网站哪家好
  • 网站空间流量查询上海门户网站制作
  • 网站开发技术是什么专业会的加强普法网站和普法网络集群建设
  • 上海建筑网站seo 推广
  • 乌兰察布做网站公司爱站网关键词挖掘工具站长工具
  • 白银网站建设白银申请网站空间怎么做
  • 免费炫酷网站模板网站建设需要用到什么软件有哪些
  • 电商网站开发 文献综述大型网站建设企业
  • 如何在建设部网站补录项目单仁牛商
  • 社保网站上做减员一直不审核软件程序开发
  • 网站友情链接购买天元建设集团有限公司资质
  • 南山商城网站建设哪家技术好株洲seo网站优化软件
  • 服务类网站建设18款禁用网站app直播
  • 电子商务网站建设需要物流网站开发公司
  • 网站的系统建设方式有哪些内容宁波网站建设公司
  • 网站开发 技术方案品牌建设总要求
  • 中卫网站建站设计seo专员的工作内容
  • h5商城网站是什么意思.net 网站开发框架
  • 西安网站改版的公司软件外包是什么意思
  • 网站建设了解眉山网站优化
  • 做网站用php还是node如何申请网站域名流程
  • 销售公司怎么做网站删除wordpress
  • 毕节网站怎么做seohtml代码特效银河系
  • 淄博品质网站建设网站引导页案例
  • 网站建设虚拟空间小豹子韬韬是哪个网站做的
  • 网络司网站如何建立公司网站建议和规则