前言
本系列内容为程序媛学习C++时做的笔记。以代码为主,并备注了打印结果以及详尽的解释注释。希望对你有所帮助。
对象继承
#include <iostream>
using namespace std;
class Animal {
private:
char *name;
public:
Animal(char *name) { this->name = name; }
void printName() {
cout << name << endl;
}
};
//这样写: class Pig : Animal
//默认继承是private Animal,子类在类外面不能调用printName(),否则编译报错
//要加public继承,才能在pig外面调用,否则(私有继承)只能在子类里面访问父类成员
class Pig : public Animal {
private:
int age;
public:
Pig() : Animal("小花") {}
Pig(char *name) : Animal(name) {}
//继承父类的同时,给自己的成员age初始化
Pig(char *name, int age) : Animal(name), age(age) {}
void printNameAge() {
//不是public Animal,也可以调用printName();
printName();
cout << age << endl;
}
};
int main() {
Pig pig("小黑", 111);
pig.printName();//如果不是public Animal,该行编译报错 //输出小黑
pig.printNameAge();//小黑 111
return 0;
}
对象属性初始化:
class Course {
private:
string course;
public:
Course(string course) : course(course) {}
};
class Person {
private:
string name;
public:
Person(string name) : name(name) {}
};
class Student : public Person {
private:
Course course;
public:
Student() : Person("张三"), course("语文") {}//第一种初始化方式
Student(Course cou) : Person("李四"), course(cou) {}//第2种初始化方式
};
多继承的二义性问题
C++是有多继承的
Java语言不允许多继承,多继承有歧义,如果Java语言多继承 就会导致代码不健壮,(二义性)
解决1:
#include <iostream>
using namespace std;
class Base1 {
public:
void onCreate() {};
void onStart() {};
};
class Base2 {
public:
void onCreate() {};
void onStart() {};
};
class Activity : public Base1, public Base2 {
public:
//没有重写onCreate()方法
void onStart() {};
};
int main() {
Activity ac;
//ac.onCreate();//不知道调用哪个父类的方法,所以有歧义,编译报错,可以如下调用:
ac.Base2::onCreate();//明确指定调用谁的
// 这个是优先寻找子类的函数,因为特别明确,没有问题,还没有产生歧义(二义性)
ac.onStart();
return 0;
}
二义性原因:
Base1和Base2都有onCreate方法
解决:
::指定说明调用谁的方法 Base2::
或者子类直接重写方法。 void onStart() {};
解决2:
#include <iostream>
using namespace std;
class Obj {
public:
int number;
};
class Base1 : virtual public Obj {
};
class Base2 : virtual public Obj {
};
class Use : public Base1, public Base2 {
};
int main() {
Obj obj;
Base1 base1;
Base2 base2;
Use use;
obj.number;
base1.number;
base2.number;
use.number;
return 0;
}
二义性原因:
Object有number,父类1和2都给继承了过来。Son在用的时候就不知道用哪个父类的了。
解决:
虚继承,让number只存在Obj里面,不给继承到Base1/Base2里。调用的时候就明确知道调用的都是Obj里面的。
运算符重载
#include <iostream>
using namespace std;
class AddXY {
public:
int x, y;
// 系统C++源码,大量使用此方式 :x(x), y(y)
AddXY(int x, int y) : x(x), y(y) {}
};
// 把+重载 运算符重载
// 在真实开发过程中,基本上都是写在类的里面的? 答:外部是不能获取内部的私有成员的
AddXY operator+(AddXY a, AddXY b) {
return AddXY(a.x + b.x, a.y + b.y);
}
int main() {
AddXY a(1, 2);
AddXY b(3, 4);
AddXY c = a + b;
cout << c.x << endl;//4
cout << c.y << endl;//6
return 0;
}
类里面运算符重载
举例1:
class AddXY {
public:
//写在里面省一个入参
// 系统是这样写的 常量引用:不允许修改,只读模式
// const 关键字的解释
// & 性能的提高,如果没有& 运行+ 构建新的副本,会浪费性能
// 如果增加了& 引用是给这块内存空间取一个别名而已
AddXY operator+(const AddXY &b) {
return AddXY(this->x + b.x, this->y + b.y);//b.y=4
}
};
调用:
a+b;//输出同上
举例2:
class AddXY {
public:
void operator++(int) {//对象++ (++对象没有入参int)
this->x = this->x + 1;
this->y = this->y + 1;
}
};
调用:
AddXY a(1, 2);
a++;
cout << a.x << endl;//2
cout << a.y << endl;//3
举例3:
重载系统的输入输出运算符。
class Sun {
public:
int x, y;
Sun() {}
Sun(int x, int y) : x(x), y(y) {}
// istream 输入 系统的 >>
// ostream 输出 系统的 <<
friend ostream &operator>>(ostream &_START, const Sun &sun) {
_START << "重载>>运算符" << endl;
return _START;
}
friend istream &operator>>(istream &_START, Sun &sun) {//没有const,有const的sun.x就不给赋值了
_START >> sun.x;//第一次输入的值给x
_START >> sun.y;//第二次输入的值给y
//_START >> derry.x >> derry.y;//简化写法
}
};
调用:
Sun sun;
cout >> sun >> sun >> sun;//调用我们重载的
//输出
//重载>>运算符
//重载>>运算符
//重载>>运算符
调用:
Sun sun;
cin >> sun;//调用我们重载的
cout << sun.x << "~" << sun.y << endl;
// 11(回车)
// 22(回车)
// 11~22
重载括号运算符
#include <iostream>
using namespace std;
class ArraySun {
private:
int arr[10];
public:
void set(int index, int value) {
arr[index] = value; // []目前不是我的
}
int operator[](int index) {//自定义[]
cout << "第" << index << "个元素是:" << this->arr[index] << endl;//调用系统的[]
return this->arr[index];
}
};
int main() {
ArraySun arrs;
arrs.set(0, 111);
arrs.set(1, 222);
arrs.set(2, 333);
//调用自定义的[]
arrs[2] ; //第2个元素是:333
return 0;
}