菱形继承
菱形继承是因为多继承存在问题而存在的
像这样都是a的话出现二义性,要采用virtual继承,所以菱形继承它也叫虚继承。
#include<iostream> #include<string> using namespace std; class A { public: A(int a) : a(a){} protected: int a = 555; }; class B : public A { public: B(int a):A(a){} }; class C : public A { public: C(int a): A(a){} }; class D : public B, public C { public: D(int a): B(90), C(68) {} void print() { cout << A::a << endl; cout << B::a << endl; cout << C::a << endl; } }; int main() { D d(10); d.print(); system("pause"); return 0; }
如结果所示,存在二义性问题,这a应该都是一个值,采用virtual继承的方式来解决
在B,C的继承方式前加个virtual,这样子类就必须调用爷爷的构造函数
#include
#include
using namespace std;
class A
{
public:
A(int a) : a(a){}
protected:
int a = 555;
};
class B : virtual public A
{
public:
B(int a):A(a){}
};
class C : virtual public A
{
public:
C(int a): A(a){}
};
class D : public B, public C
{
public:
D(int a): B(90), C(68),A(a) {}
void print()
{
cout << A::a << endl;
cout << B::a << endl;
cout << C::a << endl;
}
};
int main()
{
D d(10);
d.print(); system("pause"); return 0;
}
如图所示,打印的结果都是10,这样就不存在二义性问题了
继承中的同名问题
就2种
1.数据成员同名
2.函数同名
在对象的访问中:
如果不加以修饰,那么按照就近原则,
如果用类名限定了,那么自然就调用那类中的
用指针访问时候
注意的是:可以用父类的指针,对子类对象进行初始化,但不能用子类的指针对父类初始化
1.如果不加以修饰,那么调用的,取决于指针的类型,如果是父类的指针类型,那么肯定就调用父类的。
#include<iostream> #include<string> using namespace std; class father { public: father(){} father(string name):name(name){} protected: string name; }; class son : public father { public: son(){} son(string name1, string name2) :father("father") { this->name = "son"; } void print() { cout << son :: name << endl; cout << father::name << endl; } protected: string name; }; int main() { son m; m.print(); father* p = new son; p->print(); system("pause"); return 0; }
如果所示,这里是父类的指针类型,只能调用父类的东西,调用了子类的东西,编译器自然就报错了。
重载加常量情况
主要是: 有个MM类,它的对象为mm
1.mm = mm + 1
2.mm = 1 + mm
运算符重载的使用情况
#include<iostream> #include<string> using namespace std; class MM { public: MM(int date) : date(date) {} MM operator + (int m) { this->date = this->date + m; return *this; } void print() { cout << date << endl; } private: int date; }; int main() { MM mm(1); mm = mm + 1; // 采用的函数运算符重载 , 实质是: mm.成员函数() mm = 1 + mm; // 报错的原因是 1.成员函数() 1无法完成这种转化 mm.print(); system("pause"); return 0; }
解决这一问题的方法:就是要使用友元函数的运算符重载
#include<iostream> #include<string> using namespace std; class MM { public: MM(int date) : date(date) {} /*MM operator + (int m) { this->date = this->date + m; return *this; }*/ friend MM operator + (MM date1,MM date2) { return MM(date1.date + date2.date); } void print() { cout << date << endl; } private: int date; }; int main() { MM mm(1); mm = mm + 1; // 采用的函数运算符重载 , 实质是: mm.成员函数() mm = 1 + mm; // 报错的原因是 1.成员函数() 1无法完成这种转化 //使用友元函数重载,来解决这一问题 mm.print(); system("pause"); return 0; }
委托构造
构造委托也叫做委托构造,它能够允许有一个构造函数调用另外一个构造函数
它只能采用初始化列表
c++中大部分情况,都需要初始化列表,所以建议,最好每次都是用初始化参数列表
#include<iostream> #include<string> using namespace std; class MM { public: MM(): MM(10, "温柔了岁月") {} //这就是委托构造,采用初始化列表 MM(int age , string name) : age(age),name(name){} private: int age; string name; }; int main() { system("pause"); return 0; }