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

C++基础——多继承问题

2012-03-20 13:12 429 查看
本文主要介绍C++的多继承问题,包括基类和派生类的 构造函数、析构函数调用顺序,基类父类虚函数的调用……
详情请见代码注释

书本上讲得再多,还不如自己动手测试:

头文件:class.h:

#ifndef CLASS_H_
#define CLASS_H_
#include <iostream>
#include <string>
using namespace std;
class s1
{
public:
s1(int n=0,string str="NoName");
virtual~s1();
int GetTotalCount()const;
void ShowCurrentCount()const;
int GetNum()const;
string GetName()const;
void SetName(string& str);
void ChangeNum(int& n);
virtual void Show()const;

private:
string m_strName;//为每一个对象取一个名字
int m_nNum;//一个任意的变量没意义
static int m_nTotalCount;//记录当前类类型的总数目
};
int s1::m_nTotalCount=0;//初始化时记得在前面加上变量类型int
//使用成员初始化列表初始化类成员
s1::s1(int n,string str):m_nNum(n),m_strName(str)//默认参数的函数在实现时不要带上默认参数
{
m_nTotalCount++;
cout<<"s1的构造函数被调用,对象名为:"<<m_strName<<"\n========================================================"<<endl;
}
s1::~s1()
{
cout<<"s1的析构函数被调用,对象名为:"<<m_strName<<"\n========================================================"<<endl;
}
int s1::GetTotalCount()const
{
return m_nTotalCount;
}
void s1::ShowCurrentCount()const
{
cout<<"当前对象数目为:"<<m_nTotalCount<<endl;
}
int s1::GetNum()const
{
return m_nNum;
}
string s1::GetName()const
{
return m_strName;
}
void s1::SetName(std::string &str)
{
m_strName=str;
}
void s1::ChangeNum(int &n)
{
m_nNum=n;
}
void s1::Show()const
{
cout<<"s1的Show()函数:"<<endl;
cout<<"当前对象的m_nNum值是:"<<m_nNum<<endl;
cout<<"当前对象的名称是:"<<m_strName;
cout<<"当前正有"<<m_nTotalCount<<"个对象存在"<<endl;
}
///////////////////////////////////////////////////////////////////////////
//class s2继承自s1
class s2:virtual public s1
{
public:
s2(string num="000001",int n=1, string str="name_s2");
virtual~s2();
virtual void Show()const;
private:
string m_strName;
string number;
};
s2::s2(string num,int n,string str):s1(n,str),number(num)
{
cout<<"s2的构造函数被调用\n---------------------------------------"<<endl;
}
s2::~s2()
{
cout<<"s2的析构函数被调用\n--------------------------------------------------------------------"<<endl;
}
void s2::Show()const
{
cout<<"s2的Show()函数:"<<endl;
cout<<"the numberof this class is:"<<number<<endl;
}
///////////////////////////////////////////////////////////////////////////////////////////
//class s3继承自s1
class s3:virtual public s1
{
public:
s3(string str="name_s3");
virtual~s3();
virtual void Show()const;
private:
string m_strName;
};
s3::s3(string str)
{
cout<<"s3的构造函数被调用\n----------------------------------------------"<<endl;
}
s3::~s3()
{
cout<<"s3的析构函数被调用\n----------------------------------------"<<endl;
}
void s3::Show() const
{
cout<<"s3的Show()函数:"<<endl;
cout<<"the name of this class is:"<<m_strName<<endl;
}
/////////////////////////////////////////////////////////////////////////////////////////////////
//class s4继承自s2和s3
class s4: public s2,public s3
{
public:
s4();
virtual~ s4();
void Show()const;
};
s4::s4()
{
cout<<"s4的构造函数被调用\n------------------------------------------------"<<endl;
}
s4::~s4()
{
cout<<"s4的析构函数被调用\n----------------------------------------"<<endl;
}
void s4::Show()const
{
cout<<"这是s4的Show()函数"<<endl;
}

#endif;

主函数:

/ C++继承机制.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include "class.h"
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
/*	{
s1 s;//s的生命周期在花括号里
}
/*cout<<"已经跳出花括号"<<endl;
s1 a(3,"jelin"),b(4,"boy"),c(5,"gril"),d(45,"dsjfh"),e;
a.Show();
b.Show();
c.Show();
d.Show();
e.Show();*/
/*	s2 s;
//s.Show();//派生类可以直接调用父类的方法
string str="linda";
s.SetName(str);
s1* pS1=&s;//基类指针可以指向派生类对象
pS1->Show();//基类指针调用的函数是这个指针指向的类型的成员函数(S2的)
s3 s,a;
s.Show();
s.ShowCurrentCount();//结果为1,因为派生类构造时也调用基类构造函数生成了基类对象*/
/*s4继承自s2和s3,构造函数的调用顺序是:
s1-->s2-->
s1-->s3-->
s4
析构函数的调用顺序则是按照派生链的顺序由基类到派生类的方向:
s4-->
s3-->s1-->
s2-->s1
由于是多继承机制,s1被构造了2次,也被析构了两次
解决办法是:虚基类class2:public virtual class1
其中public virtual 的顺序无所谓
*/
s4 ss;
ss.Show();
//s.Show();
/*s将调用派生链中最新的函数(即离s4最近的父类)此处出错,
由于派生自s2和s3,二者都有Show()函数,引起了二义性*/
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: