C++--被遗弃的多重继承、经典问题
一.被遗弃的多重继承
Q:C++中是否允许一个类继承自多个父类? 但是在多重继承中会存在许多问题 Q:多重继承得到的对象可能拥有不同的地址 代码示例 #include <iostream> #include <string> using namespace std; class BaseA { int ma; public: BaseA(int a) { ma = a; } int getA() { return ma; } }; class BaseB { int mb; public: BaseB(int b) { mb = b; } int getB() { return mb; } }; class Derived : public BaseA,public BaseB//拥有两个父类 { int mc; public: Derived(int a,int b,int c) : BaseA(a),BaseB(b) { mc = c; } int getC() { return mc; } void print() { cout << "ma = " << getA() << "," << "mb = " << getB() << "," << "mc = " << mc << endl; } }; int main() { cout << "sizeof(Derived) = " << sizeof(Derived) << endl; Derived d(1,2,3); d.print(); cout << "d.getA() = " << d.getA() << endl; cout << "d.getB() = " << d.getB() << endl; cout << "d.getC() = " << d.getC() << endl; cout << endl; //两个父类指针指向同一个对象 BaseA* pa = &d; BaseB* pb = &d; cout << "pa->getA() = " << pa->getA() << endl; cout << "pb->getB() = " << pb->getB() << endl; cout << endl; void* paa = pa; void* pbb = pb; if( paa == pbb ) { cout << "Pointer to the same object!" << endl; } else { cout << "Error" << endl; } cout << "pa = " << pa << endl; cout << "pb = " << pb << endl; cout << "paa = " << paa << endl; cout << "pbb = " << pbb << endl; return 0; } 运行结果 我们可以看到在条件判断语句中,paa与pbb指向的是同一个对象,按理说应该打印相同时的语句,可是却打印错误,从接下来的地址打印结果是不一样的,这就造成了多重继承的问题--同一个对象取地址之后进行初始化,但是pa与pb打印的结果却不同 Q:多重继承可能产生冗余的成员 代码实现 #include <iostream> #include <string> using namespace std; class People { string m_name; int m_age; public: People(string name,int age) { m_name = name; m_age = age; } void print() { cout << "Name = " << m_name << "," << "Age = " << m_age << endl; } }; class Teacher : virtual public People { public: Teacher(string name,int age) : People(name,age) { } }; class Student : virtual public People { public: Student(string name,age) { } }; class Doctor : public Teacher,public Student { public: Doctor(string name,int age) : Teacher(name,age),Student(name,People(name,age) { } }; int main() { Doctor d("Delphi",33); d.print(); return 0; } 由运行结果可以知道,在进行print时出错,这是因为Doctor由于继承,会有两个打印的函数,所以通过作用域分辨符进行改正 由于冗余,打印的结果可能不一样 当多重继承关系出现闭合时将产生暑假冗余的问题 解决方案:虚继承 二.经典问题分析一.关于动态内存分配 #include <iostream> #include <string> #include <cstdlib> using namespace std; class Test { int* mp; public: Test() { cout << "Test::Test()" << endl; mp = new int(100); cout << *mp << endl; } ~Test() { delete mp; cout << "~Test::Test()" << endl; } }; int main() { Test* pn = new Test; Test* pm = (Test*)malloc(sizeof(Test)); delete pn; free(pm); return 0; } 运行结果 关于动态内存分配 new和malloc的区别 1.new在所有C++编译器中都能被支持,malloc在某些系统开发中是不能调用的 2.new能够触发析构函数的调用,malloc仅分配需要的内存空间 3.对象的创建只能使用new,malloc不适合面向对象开发 delete和free的区别 1.delete在所有C++编译器中都被支持,free在某些系统开发中是不能调用的 2.delete能够触发析构函数的调用,free仅归还之前的分配空间 3.对象的销毁只能使用delete,free不适合面向对象的开发 B.关于虚函数 Q:构造函数中是否可以发生多态?析构函数是否可以发生多态? 编译器会检查dynamic_cast的使用是否正确,类型转换的结果只可能在运行的阶段才能得到 代码示例 #include <iostream> #include <string> using namespace std; class Base { public: Base() { cout << "Base::Base()" << endl; } virtual ~Base()//析构虚函数 { cout << "Base::~Base()" << endl; } }; class Derived : public Base { }; int main() { Base* p = new Derived;//指向的是子类对象 Derived* pd = dynamic_cast<Derived*>(p);//强制转换 cout<<"pd="<<pd<<endl; if( pd != NULL ) { cout << "pd = " << pd << endl; } else { cout << "Cast error!" << endl; } delete p; return 0; } 将其修改之后的打印结果比较 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |