给网站做图,vps可以做wordpress和ssr,调用wordpress数据,网页设计作业报告范文1  继承 C的继承是弱继承  继承的语法#xff1a; class  子类 : 继承方式1  基类1,  继承方式2  基类2,  ...  { ... }; 继承方式#xff1a; 共有继承  public 保护继承  protected 私有继承  private   
2  继承的基本属性#xff08;3种继承方式均有#xff09; 继承所… 
1  继承 C的继承是弱继承  继承的语法 class  子类 : 继承方式1  基类1,  继承方式2  基类2,  ...  { ... }; 继承方式 共有继承  public 保护继承  protected 私有继承  private   
2  继承的基本属性3种继承方式均有 继承所要达到的目的 子类对象包含基类子对象  子类内部可以直接访问基类的所有非私有成员 
// derived.cpp 继承最基本的特点:
// (1) 子类对象 内部包含 基类(子)对象
// (2) 子类内部可以访问 基类的 非私有(公有/保护)成员(变量/函数)
#include iostream
using namespace std;
class Base {
public:int m_a;void foo() { cout  Base::foo  endl; }
protected:int m_b;void bar() { cout  Base::bar  endl; }
private:int m_c;void hum() { cout  Base::hum  endl; }
};
//class Derived : public Base {
//class Derived : protected Base {
class Derived : private Base {
public:void fun() {m_a  100; // okfoo();     // okm_b  200; // okbar();     // ok, 以上四行代码证明子类内部可以直接访问基类的公有和保护成员
//      m_c  300; // error
//      hum();     // error,以上两行代码证明子类内部不可以直接访问基类的私有成员}
private:int m_d;
};
// 模拟类的设计者(类库、别人设计的类、自己设计的类)
// --------------------------------
// 模拟用户(使用类的人)
int main( void ) {Base b; // 基类对象--|m_a m_b m_c|cout  基类对象b的大小:  sizeof(b)  endl; // 12Derived d; // 子类对象-- |基类子对象|m_d| -- |m_a m_b m_c|m_d|cout  子类对象d的大小:  sizeof(d)  endl; // 16return 0;
} 继承的本质 基类的非私有成员在子类中仅为可见而非子类拥有。 可见表软继承 注意关于继承切记不要理解为基类的成员变为子类的成员。继承不会改变类成员的作用域基类的成员永远都是基类的成员并不会因为继承而变成子类的成员。 尽管基类的公有和保护成员在子类中直接可见但仍然可以在子类中重新定义这些名字子类中的名字会隐藏所有基类中的同名定义定义表隐藏可见表。 如果需要在子类内部访问一个基类中定义却被子类标识符所隐藏的名字可以借助作用域限定操作符::实现。 因为作用域的不同分别在子类和基类中定义的同名成员函数包括静态成员函数并不构成重载关系相反是一种隐藏关系。 
// hide.cpp 基类和子类内部的同名定义 相互之间为隐藏关系 
#include iostream
using namespace std;
class Base {
public:int m_a;void foo() { cout  Base::foo  endl; }
protected:int m_b;void bar() { cout  Base::bar  endl; }
private:int m_c;void hum() { cout  Base::hum  endl; }
};
class Derived : public Base {
//class Derived : protected Base {
//class Derived : private Base {
public:void fun() {Base::foo(); // 子类的foo将基类的foo隐藏,但可以利用作用域限定符强制调用基类的foobar(); // 子类的bar将基类的bar隐藏}
private:int m_d;void foo() { cout  Derived::foo  endl; }void bar() { cout  Derived::bar  endl; }
};
// 模拟类的设计者(类库、别人设计的类、自己设计的类)
// --------------------------------
// 模拟用户(使用类的人)
int main( void ) {Derived d;d.fun();return 0;
} 3  三种继承方式的差别(不是重点) 基类中的公有、保护、私有成员在子类中将对这些基类成员的访问控制限定进行重新标记 工作中主要使用public继承其他极少使用。 在类的外部通过 子类对象   访问   基类的成员时需要考虑因继承方式对访问控制限定的影响 
// public.cpp 公有继承
#include iostream
using namespace std;
class Base {
public: // 原始标记int m_a;void foo() { cout  Base::foo  endl; }
protected: // 原始标记int m_b;void bar() { cout  Base::bar  endl; }
private: // 原始标记int m_c;void hum() { cout  Base::hum  endl; }
};
class Derived : public Base {// 子类将对基类的成员重新标记访控限定 m_a/foo是public m_b/bar是protected // m_c/hum是private
public:void fun() { // 子类内部访问基类的成员编译器需要查看这些基类成员在基类中的原始标记m_a  100; // okfoo();     // okm_b  200; // okbar();     // ok, 以上四行代码证明子类内部可以直接访问基类的公有和保护成员
//      m_c  300; // error
//      hum();     // error,以上两行代码证明子类内部不可以直接访问基类的私有成员}
private:int m_d;
};
// 模拟类的设计者(类库、别人设计的类、自己设计的类)
// --------------------------------
// 模拟用户(使用类的人)
int main( void ) {Derived d; // 利用子类对象在类外访问基类的成员编译器需要查看这些成员在子类中的重新标记d.m_a  1000; // okd.foo();      // ok
//    d.m_b  2000; // error
//    d.bar();      // error
//    d.m_c  3000; // error
//    d.hum();      // errorreturn 0;
} 
// protected.cpp 保护继承
#include iostream
using namespace std;
class Base {
public: // 原始标记int m_a;void foo() { cout  Base::foo  endl; }
protected: // 原始标记int m_b;void bar() { cout  Base::bar  endl; }
private: // 原始标记int m_c;void hum() { cout  Base::hum  endl; }
};
class Derived : protected Base {// 子类将对基类的成员重新标记访控限定 m_a/foo是protected   m_b/bar是protected//m_c/hum是private
public:void fun() { // 子类内部访问基类的成员编译器需要查看这些基类成员在基类中的原始标记m_a  100; // okfoo();     // okm_b  200; // okbar();     // ok, 以上四行代码证明子类内部可以直接访问基类的公有和保护成员
//      m_c  300; // error
//      hum();     // error,以上两行代码证明子类内部不可以直接访问基类的私有成员}
private:int m_d;
};
// 模拟类的设计者(类库、别人设计的类、自己设计的类)
// --------------------------------
// 模拟用户(使用类的人)
int main( void ) {Derived d; // 利用子类对象在类外访问基类的成员编译器需要查看这些成员在子类中的重新标记
//    d.m_a  1000; // error
//    d.foo();      // error
//    d.m_b  2000; // error
//    d.bar();      // error
//    d.m_c  3000; // error
//    d.hum();      // errorreturn 0;
} 
// private.cpp 私有继承
#include iostream
using namespace std;
class Base {
public: // 原始标记int m_a;void foo() { cout  Base::foo  endl; }
protected: // 原始标记int m_b;void bar() { cout  Base::bar  endl; }
private: // 原始标记int m_c;void hum() { cout  Base::hum  endl; }
};
class Derived : private Base {// 子类将对基类的成员重新标记访控限定 m_a/foo是private   m_b/bar是private   //m_c/hum是private
public:void fun() { // 子类内部访问基类的成员编译器需要查看这些基类成员在基类中的原始标记m_a  100; // okfoo();     // okm_b  200; // okbar();     // ok, 以上四行代码证明子类内部可以直接访问基类的公有和保护成员
//      m_c  300; // error
//      hum();     // error,以上两行代码证明子类内部不可以直接访问基类的私有成员}
private:int m_d;
};
// 模拟类的设计者(类库、别人设计的类、自己设计的类)
// --------------------------------
// 模拟用户(使用类的人)
int main( void ) {Derived d; // 利用子类对象在类外访问基类的成员编译器需要查看这些成员在子类中的重新标记
//    d.m_a  1000; // error
//    d.foo();      // error
//    d.m_b  2000; // error
//    d.bar();      // error
//    d.m_c  3000; // error
//    d.hum();      // errorreturn 0;
} 4  公有继承独有的特点 
4.1  子类对象在类外可以访问基类公有成员 如果被子类同名标识符隐藏可借助作用域限定符::指定访问基类的公有成员。 
// phs.cpp 公有继承独有特点:
// (1)只有在公有继承下子类对象在类外可以访问基类的公有成员(其他继承不可以)
#include iostream
using namespace std;
class Base {
public: int m_a;void foo() { cout  Base::foo  endl; }
protected: int m_b;void bar() { cout  Base::bar  endl; }
private: int m_c;void hum() { cout  Base::hum  endl; }
};
class Derived : public Base {
public:void foo() { cout  Derived::foo  endl; }
private:int m_d;
};
// 模拟类的设计者(类库、别人设计的类、自己设计的类)
// --------------------------------
// 模拟用户(使用类的人)
int main( void ) {Derived d; d.m_a  1000; // okd.foo();      // ok,只有在公有继承下子类对象在类外可以访问基类的公有成员d.Base::foo();// okreturn 0;
} 4.2  子类类型的指针(引用) 和 基类类型的指针(引用)可以进行转换 子类类型的指针 能 隐式转换为基类类型的指针  子类类型的引用 能 隐式转换为基类类型的引用 (编译器认为访问范围缩小是安全的) class  Human { ... }; class  Student : public Human { ... }; Student s; Human*  ph  s;  // 指针  访问范围缩小  Human  rh  s;   //  引用  访问范围缩小 基类类型的指针 不能 隐式转换为子类类型的指针 基类类型的引用 不能 隐式转换为子类类型的引用 (编译器认为访问范围扩大是危险的) class  Human { ... }; class  Student : public Human { ... }; Human h; Student*  ps  static_castStudent*(h); // 指针  访问范围扩大  Student  rs  static_castStudent(h);  // 引用  访问范围扩大  编译器对类型安全的检测仅仅基于指针/引用本身 基类指针/引用的实际目标究竟是不是子类对象完全由程序员自己判断 class  Human { ... }; class  Student : public Human { ... }; Student  s; Human*  ph  s; Human  rh  s; Student  ps  static_castStudent* (ph); // 访问范围扩大但安全合理 Student  rs  static_castStudent (rh); // 访问范围扩大但安全合理 #include iostream
using namespace std;
#pragma pack(1)
class Human {
public:int m_age;string m_name;
};
class Student : public Human {
public:int m_no;
};
// 模拟类的设计者(类库、别人设计的类、自己设计的类)
// --------------------------------
// 模拟用户(使用类的人)
int main( void ) {Human h; // |m_age m_name|cout  基类对象h的大小:  sizeof(h)  endl; // 36Student s; // |基类子对象|m_no| -- |m_age m_name|m_no|cout  子类对象s的大小:  sizeof(s)  endl; // 40Human* ph  s; // Student*--Human* (子类型指针--基类型指针)Human rh  s;  // 以上两种转换编译器认为访问范围缩小是安全的//    Student* ps  static_castStudent*(h); // Human*--Student* // (基类型指针--子类型指针)
//    Student rs  static_castStudent(h);  // 以上两种转换编译器认为访问范围扩大是危险的,通过强转虽然可以成功但风险依然存在// (极其不建议大家这么做)Student* ps  static_castStudent*(ph);//Human*--Student*(基类型指针--子类型指针)Student rs  static_castStudent(rh);//Human--Student(基类型引用--子类型应用)// 以人类高智商判断以上两个转换毫无风险(极其建议大家这么做) // 编译器只是简单粗暴的根据类型来判断是否存在风险return 0;
} 5  子类的构造和析构 
5.1  子类的构造函数 1子类没有定义构造函数时 编译器会为子类提供默认的无参构造函数  定义完基类子对象后调用基类的无参构造函数  2子类定义构造函数但未在初始化表中指明基类部分的构造方式时 定义完基类子对象后调用基类的无参构造函数  3子类定义构造函数并且在初始化表中指明基类部分的构造方式时 定义完基类子对象后调用指明的基类的构造函数 子类对象的构造过程 1构造基类子对象   2构造子类的成员变量   3执行自己在子类构造函数中书写的代码 阻断继承 子类的构造函数  无论如何  都会调用基类的构造函数。 若把基类的构造函数定为私有则该类的子类就永远不能被实例化为对象。 在C中可以用这种方法阻断一个类被扩展。 5.2  子类的析构函数 1子类没有定义析构函数时 编译器将提供一个默认的析构函数析构完子类所有的成员变量后 会自动调用其基类的析构函数 2子类定义了析构函数时 子类的析构函数在执行完自身析构代码并析构完所有的成员变量后 会自动调用其基类的析构函数 子类对象的析构过程 1执行自己在子类析构函数中书写的代码    2析构子类的成员变量    3析构基类子对象 5.3  子类的拷贝构造函数 1子类并没有定义拷贝构造函数时 编译器会为子类提供默认的拷贝构造函数 定义完基类子对象后调用基类的拷贝数构造函 。 2子类定义了拷贝构造函数但没有在初始化表中指明其基类部分的构造方式时 定义完基类子对象后调用基类的无参构造函数。 3子类定义了拷贝构造函数且初始化表中指明了其基类部分以拷贝方式构造时 定义完基类子对象后调用基类的拷贝构造函数。 
5.4  子类的拷贝赋值函数 1子类没有定义拷贝赋值函数时 编译器为子类提供的缺省拷贝赋值函数内部会自动调用基类的拷贝赋值函数 复制该子类对象中的基类子对象。 2子类定义了拷贝赋值函数但没有  显示调用  基类的拷贝赋值函数时 编译器不会塞任何操作子类对象中的基类子对象将得不到复制。 3子类定义了拷贝赋值函数同时  显示调用  了基类的拷贝赋值函数时 子类对象中的基类子对象将得到复制。 
// ccons.cpp 子类的构造函数 和 析构函数
#include iostream
using namespace std;class Human {
public:Human( int age0, const char* name无名 ) : m_age(age),m_name(name) {//【int m_ageage;】定义m_age,初值为age//【string m_name(name);】定义m_name,利用m_name.string(name)cout  Human类缺省构造函数被调用  endl;}Human( const Human that ) : m_age(that.m_age), m_name(that.m_name) { //【int m_agethat.m_age;】定义m_age,初值为that.m_age//【string m_name(that.m_name);】定义m_name,利用m_name.string(that.m_name)cout  Human类拷贝构造函数被调用  endl;}Human operator( const Human that ) {// 编译器不会再拷贝赋值函数中塞任何操作cout  Human类的拷贝赋值函数被调用  endl;this-m_age  that.m_age;this-m_name  that.m_name; // this-m_name.operator(that.m_name)--string类的拷贝赋值函数return *this;}~Human() {cout  Human类的析构函数被调用  endl;// 对于基本类型成员变量m_age,什么都不做// 对于类类型成员变量m_name,利用 m_name.~string()// 释放 m_age/m_name 本身所占内存空间}void getinfo( ) {cout  姓名:   m_name  , 年龄:   m_age;}
private:int m_age; // 基本类型的成员变量string m_name; // 类类型的成员变量
};
class Student : public Human {
public:void getinfo( ) {Human::getinfo();cout  , 成绩:  m_score  , 评语:  m_remark  endl;}
//  如果子类没有提供任何构造函数,编译器将提供一个无参的构造函数
/*  Student() {【Human();】定义基类子对象,利用 基类子对象.Human()【float m_score;】【string m_remark;】}*/Student( int age0, const char* name无名, float score0.0, const char* remark没有): Human(age,name), m_score(score),m_remark(remark) {//【Human(age,name);】定义基类子对象,利用 基类子对象.Human(age,name)//【float m_scorescore;】//【string m_remark(remark);】cout  Student类的缺省构造函数被调用  endl;}
//  如果子类没有提供析构函数,编译器将提供一个默认的析构函数
/*  ~Student() {对于类类型m_remark,利用m_remark.~string()对于基类子对象,利用基类子对象.~Human()释放 m_score/m_remark/基类子对象 本身所占内存空间}*/~Student() {cout  Student类的析构函数被调用  endl;// 对于类类型m_remark,利用m_remark.~string()// 对于基类子对象,利用基类子对象.~Human()// 释放 m_score/m_remark/基类子对象 本身所占内存空间}
//  如果子类没有提供拷贝构造函数,编译器将提供一个默认的拷贝构造函数
/*  Student( const Student that ) {【Human(that);】定义基类子对象,利用 基类子对象.Human(that)--Human类的拷贝构造函数【float m_scorethat.m_score;】【string m_remarkthat.m_remark;】}*/Student( const Student that ) : Human(that), m_score(that.m_score), m_remark(that.m_remark) {//【Human(that);】定义基类子对象,利用 基类子对象.Human(that)--Human类的拷贝构造函数//【float m_scorethat.m_score;】//【string m_remarkthat.m_remark;】cout  Student类的拷贝构造函数被调用  endl;}
//  如果子类没有提供拷贝赋值函数,编译器将提供一个默认的拷贝赋值函数
/*  Student operator( const Student that ) {Human rh  *this;rh  that; // rh.operator(that)--Human类的拷贝赋值函数this-m_score  that.m_score;this-m_remark  that.m_remark;return *this;}*/Student operator( const Student that ) {// 编译器不会再拷贝赋值函数中塞任何操作cout  Student类的拷贝赋值函数被调用  endl;Human rh  *this;rh  that; // rh.operator(that)--Human类的拷贝赋值函数this-m_score  that.m_score;this-m_remark  that.m_remark;return *this;}
private:float m_score;string m_remark;
};
// 模拟类的设计者(类库、别人设计的类、自己设计的类)
// --------------------------------
// 模拟用户(使用类的人)
int main( void ) {cout  -----------------s1对象的创建信息-----------------------  endl;Student s1(22,张飞,88.5,良好); // 定义s1,利用s1.Student(22,张飞,88.5,良好)s1.getinfo();cout  -----------------s2对象的创建信息-----------------------  endl;Student s2  s1; //(s1); 定义s2,利用s2.Student(s1)s2.getinfo();cout  -----------------s3对象的创建信息-----------------------  endl;Student s3;cout  s3被赋值前--;s3.getinfo();s3  s2; // s3.operator(s2)cout  s3被赋值后--;s3.getinfo();cout  -----------------main will be over----------------------  endl;return 0;
} // s1.~Student()   释放s1本身所占内存空间