继承的构造函数
详情转载:https://blog.csdn.net/K346K346/article/details/81703914
#include <iostream>
using namespace std;
class A
{
public:
A(int i, int j, int k = 5){
}
A() {};
};
class B: public A
{
public:
//B(int i, int j, int k) :A(i , j ,k){}
using A::A;
//继承A的构造函数,using:就是让某个名字在当前作用域内可见
//遇到这个代码的时候,会把基类的每个构造函数,都生成一个与之对应的派生类构造函数
// B(构造函数形参列表):A(照抄的构造函数的形参列表){}
//B(int i, int j, int k):A(i , j , k){} 编译器自动生成
//如果基类A的构造函数有默认参数,那么编译器遇到这种 using A::A的时候,会帮我们在派生类B中构造出多个构造函数来
//a)第一个构造函数是带有所有参数的构造函数
//b)其余的构造函数,每个分别省略一个默认参数
//B(int i, int j, int k) :A(i , j ,k){}
//B(int i, int j) :A(i , j){}
// 如果类B,只含有usingA::A 从A类继承来的构造函数的话,那么编译器是会给它合成默认的构造函数的。
};
int main()
{
//一个类只继承直接基类的构造函数,默认,拷贝移动构造函数不能被继承。
//B ad(3, 4 , 5);
//如果基类含多个构造函数,则多数情况下,派生类会继承所有这些构造函数,但如下例外情况:
//1)如果你在派生类中定义的构造函数与基类构造函数有相同的参数列表,那么基类中继承来的构造函数会被你在派生类中的
//定义覆盖掉(相当于只继承了一部分基类中的构造函数)
//2) 默认,拷贝,移动构造函数不会被继承。
B ad(3,4);
//B ef;
}
多重继承概述
#include <iostream>
using namespace std;
class Grand
{
public:
Grand(int i) :m_valuegrand(i)
{
cout << "调用了Grand构造函数"<< endl;
}
virtual ~Grand()
{
cout << "调用了Grand析构函数"<< endl;
}
void mymind()
{
cout << m_valuegrand << endl;
}
public:
int m_valuegrand;
public:
static int m_static;
};
//1.2
//为了能够实用,我们定义这个静态成员变量(分配内存);
//如果你在代码中不用m_static,那么就可以不用定义。
int Grand::m_static = 5;
//定义父类A
class A :public Grand
{
public:
A(int i) :Grand(i), m_valuea(i) //每个子类的构造函数负责,负责解决自己的初始化问题。
{
cout << "调用了类A构造函数"<< endl;
}
virtual ~A()
{
cout << "调用了类A析构函数"<< endl;
}
void myinfo()
{
cout << m_valuea << endl;
}
public:
int m_valuea;
};
//定义父类B
class B
{
public:
B(int i) : m_valueb(i)
{
cout << "调用了B构造函数"<< endl;
}
B(){
cout << "B的默认构造函数"<<endl;
}
virtual ~B()
{
cout << "调用了B析构函数"<< endl;
}
void myinfo()
{
cout << m_valueb << endl;
}
public:
int m_valueb;
};
//类C :同时继承类A 和 类B
//class C : A , B
//如果是默认继承,看c是struct(public) 还是class(private)
class C : public A, public B //自己管自己的父类,没有明确规定可以继承多少个父类
{
public: //1.4区分概念:显示的初始化基类和隐式的初始化基类。
C(int i, int j, int k) :A(i),B(j),m_valuec(k) //C(int i, int j, int k) :A(i) ,m_valuec(k)
{
cout << "调用了类C构造函数"<< endl;
}
virtual ~C(){
cout << "调用了类C析构函数"<< endl;
}
void myinfoC()
{
//1.1
// A::myinfo();
//B::myinfo();
//myinfo();//调用自己的info
cout << m_valuec << endl;
}
//1.1
//void myinfo(){
// }//系统调用自己的myinfo ,会覆盖掉父类的同名函数
public:
int m_valuec;
};
int main()
{
//二、1.1多重继承
//如果从多个父类来产生出子类:多重继承;
//C ctest(10, 20, 50);
//ctest.myinfoC();//50
//ctest.myinfo(); //要增加作用域,明确告诉系统掉用的是类A还是父亲的类成员
//ctest.A::myinfo();//10
//如果在自己类中定义myinfo,则会覆盖带掉父类的同名函数
//派生类包含每个基类的子对象。
//1.2静态成员变量
//属于类,不属于对象。
//Grand::m_static =1;//可以用类名
//可以用类A
//可以用类C
//ctest对象也可以
//1.3派生类构造函数与析构函数4
//构造一个派生类对象将同时构造并初始化所有的基类对象‘
//派生类的构造函数初始化列表只初始化它的直接基类, 就会让所有的类初始化。
//派生类构造函数初始化列表将实参分别传递给每个基类,基类的构造顺序和初始化列表的顺序一致。
//区分概念:显示的初始化基类和隐式的初始化基类。
//C ctest(10,20,30);
return 0;
}
从多个父类继承构造函数
class A{
public:
A(int tv) {}
};
class B{
public:
B(int tv) {}
};
class C :public A , public B
{
public:
using A::A;//继承A的构造函数 C(int tv): A(tv) {}
using B::B;//继承B的构造函数 C ( int tv): B(tv) {}
//如果一个类从它的基类中继承了,相同的构造函数,这个类必须为该构造函数定义自己的版本
C(int tv) :A(tv) ,B(tv) {}; //子类要定义同参数的构造函数 即自己的版本
};
class A{
public:
A(int tv) {}
};
class B{
public:
B(int tv) {}
};
class C :public A , public B
{
public:
using A::A;//继承A的构造函数 C(int tv): A(tv) {}
using B::B;//继承B的构造函数 C ( int tv): B(tv) {}
//如果一个类从它的基类中继承了,相同的构造函数,这个类必须为该构造函数定义自己的版本
C(int tv) :A(tv) ,B(tv) {}; //子类要定义同参数的构造函数 即自己的版本
};
强制转换
//三:类型转换
//基类指针可以指向一个派生类对象 :编译器帮助我们隐式执行这种派生类到基类的转换,转换
//成功的原因是每个派生类对象都包含一个基类对象的一部分。
//所以:基类的引用或指针式可以绑定到基类对象这部分上来的。
Grand *gp = new C(1,2,3) ;
A *ap = new C(1,2,3);
B *bp = new C(1,2,3);
delete (pg);delete (ap);delete (bp);
C myc(6, 7,8);
Grand mygrand(myc);//临时对象