#include "iostream"
using namespace std;
int main() {
cout << "hello world" << endl;
// system("pause"); // 这个应该只在windows有效
cout<<"请按任意键继续";
cin.ignore();
return 0;// 可以不写,编译器会自动加上
}
标准形式
int main(int arg,char* argv[]) {
return 0;
}
命名空间
区分同名变量或函数
#include "iostream"
using namespace std;
namespace stu {
void sort() {
cout << "stu sort" << endl;
}
}
namespace sta {
void sort() {
cout << "stu sta" << endl;
}
}
int main(int arg, char *argv[]) {
stu::sort();
sta::sort();
cin.ignore();
return 0;
}
#include "iostream"
using namespace std;
int main(int arg, char *argv[]) {
int *a = new int(1);
cout << *a;
delete a;
return 0;
}
// new 和 delete 可以出发构造和析构
给变量起别名
本质:指针常量(指向不可变,指向的值可以变)
#include "iostream"
using namespace std;
int main(int arg, char *argv[]) {
int a = 12;
int &c = a;
c = 39;
cout<
其他类型的引用
int main(int arg, char *argv[]) {
/// 数组的引用
int arr[12];
int (&p)[12] = arr;
/// 二维数组引用
int arr2[2][3];
int (&p2)[2][3] = arr2;
/// 指针的引用
int b = 12;
int *point = &b;
int* &p3 = point;
*p3 = 32;
return 0;
}
引用当作函数参数
#include "iostream"
using namespace std;
void fun(int &a){
cout<
交换两个值
#include "iostream"
using namespace std;
void swap(int &a, int &b) {
int temp = a;
a = b;
b = temp;
}
void swap1(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
int main(int arg, char *argv[]) {
int a = 13;
int b = 14;
swap(a, b);
cout << " a " << a << " b " << b << endl;
swap1(&a, &b);
cout << " a " << a << " b " << b << endl;
return 0;
}
引用与指针的区别
&的三种作用
函数参数默认值
#include "iostream"
using namespace std;
void func(int a = 333){
cout<
函数重载
函数名称相同,函数参数个数、类型、顺序不同
成员变量和成员函数分开存储 在c++中,类内的成员变量和成员函数是分开存储的 空对象占用内存空间是 1 byte why:每个空对象也分配一个字节空间,是为了区分空对象占内存的位置 每个空对象也应该有一个独一无二的内存地址 只要是空的,占用一个字节,否则,看成员
同时虚函数也是占用内存的
定义:具有相同属性和行为的对象的集合
#include "iostream"
using namespace std;
class CPeople {
public:
int a;
public:
void fun() {
cout << "fun" << endl;
}
};
int main(int arg, char *argv[]) {
CPeople cp;
cp.a = 3;
cp.fun();
cout << "点击任意键继续";
cin.ignore();
return 0;
}
修饰符 | |
---|---|
public | 公开的 |
protected | 受保护的(本类,子类) |
private | 私有的(类内) |
c++中class 和 struct唯一的区别:成员默认修饰符不同
class默认private,struct默认public
访问私有成员
友元函数
#include "iostream"
using namespace std;
class Stu {
friend void func1();
private:
int age;
void fun() {
age = 12;
cout << age << endl;
}
protected:
void func1(){
cout << "protected" << endl;
}
};
// 友元函数
void func1() {
Stu stu;
stu.fun();
stu.func1();
}
int main(int arg, char *argv[]) {
func1();
return 0;
}
友元类
#include "iostream"
using namespace std;
class Stu {
friend void func1();
friend class Teach;
private:
int age;
void fun() {
age = 12;
cout << age << endl;
}
protected:
void func1() {
cout << "protected" << endl;
}
};
// 友元函数
void func1() {
Stu stu;
stu.fun();
stu.func1();
}
// 友元类
class Teach {
public:
Stu stu2;
void fun2() {
stu2.func1();
}
};
int main(int arg, char *argv[]) {
Teach t;
t.fun2();
return 0;
}
缺点:破坏了类的封装性
声明指针不会走构造函数,只有 new Class 的时候才去走构造函数
#include "iostream"
using namespace std;
class Stu {
public:
int age;
string name;
public :/// 构造重载
Stu() {};
Stu(int age, string name) : age(age), name(name) {};
Stu(int age);/// 类定义
public:
void func(int age);
};
/// 这种写法用在多文件的时候
Stu::Stu(int age) {
this->age = age;
};
void Stu::func(int age) {
this->age=age;
}
int main(int arg, char *argv[]) {
Stu stu(3, "张三");
cout << stu.age << " " << stu.name << endl;
Stu *stu1 = new Stu(3, "张三");
cout << stu1->age << " " << stu1->name << endl;
return 0;
}
#include "iostream"
using namespace std;
class Stu {
/// const 的修饰必须初始化
public:
int b;
int &a;
public:
/// 此时a无效的,c被回收了
/*Stu(int c) : a(c), b(c) {
}*/
/// 此时a无效的,c被回收了
Stu(int &c) : a(c), b(c) {
}
};
int main(int arg, char *argv[]) {
int age = 3;
Stu stu(age);
cout<
清理工作,有且只有一个,不能有参数,默认有一个析构函数
#include "iostream"
using namespace std;
class Stu {
public:
Stu() {
cout << "构造函数" << endl;
}
~Stu() {
cout << "析构函数" << endl;
}
};
int main(int arg, char *argv[]) {
Stu stu;
return 0;
}
指针对象delete和临时对象
#include "iostream"
using namespace std;
class Stu {
public:
Stu() {
cout << "构造函数" << endl;
}
~Stu() {
cout << "析构函数" << endl;
}
};
int main(int arg, char *argv[]) {
Stu *stu = new Stu();
/// 遇到delete才回去调用析构
delete stu;
/// 临时对象
Stu(); // 只是当前行作用域
return 0;
}
#include "iostream"
using namespace std;
class Stu {
public:
int *pp;
public:
Stu() {
pp = new int(10);
cout << "构造函数" << endl;
}
~Stu() {
// 自己的new的对象必须释放
delete pp;
cout << "析构函数" << endl;
}
};
int main(int arg, char *argv[]) {
return 0;
}
new delete 和 malloc free区别
new delete 在c++中可以分别出发构造函数和析构函数
malloc free 不会触发
其他没有区别
this指针
作用:
区分同名的
是指向当前对象的指针,所以我们可以通过指针,访问成员
常函数
只有成员函数,可以加const
特点:
可以使用成员属性,不可修改,可以使用
常函数只能调用常函数
常对象只能调用常函数
#include "iostream"
using namespace std;
class Stu {
int a;
public :
Stu() {
a = 23;
}
public:
void show() const {
update();
cout << "show hello world" << a << endl;
}
void update() const {
}
void show1() {}
};
int main(int arg, char *argv[]) {
const Stu stu;
stu.show();
return 0;
}
静态成员
静态属性类外初始化
常量静态整型可以类内直接初始化
#include "iostream"
using namespace std;
class Stu {
public :
static int a;
/// const的修饰的静态整型可以类内直接初始化
const static int b = 3;
};
int Stu::a = 3;
int main(int arg, char *argv[]) {
Stu stu;
return 0;
}
本质是构造函数
默认拷贝是浅拷贝
#include "iostream"
using namespace std;
class Stu {
public:
int a = 0;
public :
Stu() {}
/// 定义构造
Stu(const Stu &a) {
this->a=a.a;
}
};
int main(int arg, char *argv[]) {
Stu s0;
Stu s1(s0); s1.a++;
Stu s2 = s1;
Stu s3 = Stu(s1);
Stu *s4 = new Stu(s1);
cout<<s1.a<<endl;
cout<<s2.a<<endl;
cout<<s3.a<<endl;
cout<<s4->a<<endl;
return 0;
}
深拷贝
有指针成员的话
利用 new 和 memocp ,strcpyd 等开辟新的内存
函数声明要加inline
函数定义要加inline,注意只写声明位置不管事
作用:用相应的代码替换调用
比常规函数稍快,代价占用更多内存
inline void fun(){
}
虽然定义了内联函数,具体调用取决于编译器
#include "iostream"
using namespace std;
#define SUM(x) x*x;
inline void fun(int i) {
cout << (i * i);
}
int main(int arg, char *argv[]) {
cout << SUM(2 + 3);
fun(2 + 3);
return 0;
}
类与内联合函数
类内定义的都是内联函数(包括显示和隐式)
定义在外:
有 inline是内联
没有inline不是内联
内联函数与多文件:通常内联函数写在文件里
关键字operator
有四种运算符无法重载: :: 、.* 、. 、?:
#include "iostream"
using namespace std;
class Stu {
public :
int age;
double score;
Stu() {
age = 3;
score = 10.0;
}
Stu(int age):age(age){};
};
int operator+(Stu &s1, int a) {
return s1.age + a;
}
int operator+(int a, Stu &s1) {
return s1.age + a;
}
Stu operator+(Stu &s1, Stu &s2) {
return Stu(s1.age + s2.age);
}
int main(int arg, char *argv[]) {
Stu s1,
s2;
cout << 12 + s1 + s1 + s2 + 12<< endl;
return 0;
}
#include "iostream"
using namespace std;
class Stu {
public :
int age;
double score;
Stu() {
age = 3;
score = 10.0;
}
Stu(int age) : age(age) {};
int operator+(int a) {
return this->age + a;
}
Stu operator+(Stu &s2) {
return Stu(this->age + s2.age);
}
};
/*
int operator+(Stu &s1, int a) {
return s1.age + a;
}
int operator+(int a, Stu &s1) {
return s1.age + a;
}
Stu operator+(Stu &s1, Stu &s2) {
return Stu(s1.age + s2.age);
}*/
int main(int arg, char *argv[]) {
Stu s1,
s2;
/// 左侧必须是个类,所以第二种无法实现
cout << s1 + 12 << endl;
// cout<<12+s1<
个人总结:
一元运算符,建议类内
二元运算符,可以类外,也可以类内
= 、[]、()、->必须是类内
#include "iostream"
using namespace std;
class Stu {
public :
int age;
Stu(int age) : age(age) {}
/// 这个更适合类内
bool operator>=(Stu &s2) {
return this->age >= s2.age;
}
};
int main(int arg, char *argv[]) {
Stu s1(90),
s2(60);
cout << (s1 >= s2) << endl;
return 0;
}
多练练就会了,不是很难,坚持
#include "iostream"
using namespace std;
class Stu {
public :
int age;
Stu(int age) : age(age) {}
};
Stu operator-(Stu &s){
return Stu(-s.age);
}
int main(int arg, char *argv[]) {
Stu s1(90),
s2(60);
cout << (-s1).age<
#include "iostream"
using namespace std;
class Stu {
public :
int age;
Stu(int age) : age(age) {}
};
// 返回自己,所以不会释放内存
ostream& operator<<(ostream& os,const Stu& stu){
os<>(istream& is,const Stu& stu){
if (is.fail()){
cout<<"输入失败"<>stu.age;
return is;
}
int main(int arg, char *argv[]) {
Stu s1(90),
s2(60);
// cout<>s1;
cout<
#include "iostream"
using namespace std;
class Stu {
public :
int age;
Stu(int age) : age(age) {}
int operator=(int a) {
return this->
age + a;
}
Stu &operator+=(int a) {
this->
age += a;
return *this;
}
};
int main(int arg, char *argv[]) {
Stu s1(90),
s2(60);
(s1 += 30) += 30;
cout<
#include "iostream"
using namespace std;
class Stu {
public :
int age;
Stu(int age) : age(age) {}
int operator[](int index) {
switch (index) {
case 0:
return this->
age;
}
return -1;
}
};
int main(int arg, char *argv[]) {
Stu s1(90),
s2(60);
cout << s1[1] << endl;
return 0;
}
重载类型转换
#include "iostream"
using namespace std;
class Stu {
public :
int age;
Stu(int age) : age(age) {}
/// 用常函数,防止修改
operator int() const {
return this->age;
}
};
int main(int arg, char *argv[]) {
Stu s1(90),
s2(60sl
cout<<(int)s1<
#include "iostream"
using namespace std;
class People {
public:
void study() {
cout << "学习" << endl;
}
protected:
void run() {
cout << "运动" << endl;
}
private:
void showId(){
cout<<"showId"<
继承修饰符
修饰符 | |
---|---|
public | 父类怎么样,子类就怎么样 |
protected | 父类public降级protected |
private | 父类public、protected降级private |
如果不写默认private
#include "iostream"
using namespace std;
class People {
public:
People() {
cout << "People 构造函数" << endl;
}
People(int a) {
cout << "People 构造函数" << a << endl;
}
public:
void study() {
cout << "学习" << endl;
}
protected:
void run() {
cout << "运动" << endl;
}
private:
void showId() {
cout << "showId" << endl;
}
public:
~People() {
cout << "People 析构函数" << endl;
}
};
class Child : public People {
public:
Child() {
cout << "Child 构造函数" << endl;
}
public:
void gotoPark() {
this->study();
cout << "gotoPark" << endl;
}
~Child() {
cout << "Child 析构函数" << endl;
}
};
int main(int arg, char *argv[]) {
Child child;
// child.study();
child.gotoPark();
return 0;
}
友元不能被继承
多态是一种泛型编程思想
虚函数是实现这个思想的语法基础:父类的指针调用子类的函数
重写
#include "iostream"
using namespace std;
class People {
public:
/// 使用virtual实现子类方法重写
virtual void show() {
cout << "People" << endl;
}
};
class Child : public People {
public:
/// 子类重写后,这个方法前面 默认有个 virtual,可以再找个当前类的子类测试
void show() {
cout << "Child" << endl;
}
};
int main(int arg, char *argv[]) {
People *p1 = new Child();
p1->show();
return 0;
}
释放父类指针,调用父类析构的同时 也要调用子类析构
#include "iostream"
using namespace std;
class People {
public:
virtual ~People() {
cout << "父类虚析构" << endl;
}
};
class Child : public People {
public:
~Child() {
cout << "子类虚析构" << endl;
}
};
int main(int arg, char *argv[]) {
People *p1 = new Child();
delete p1;
return 0;
}
纯虚函数所在的类叫做抽象类
子类继承时必须实现
#include "iostream"
using namespace std;
class People {
public:
virtual void show() = 0;
};
class Child : public People {
public:
void show() override {
cout << "hello world" << endl;
}
};
int main(int arg, char *argv[]) {
People *p1 = new Child();
p1->show();
return 0;
}
解决棱形继承问题
了解即可
#include "iostream"
using namespace std;
class A{
public:int a;
public:A(){
a= 10;
}
};
class B:virtual public A{};
class C:virtual public A{};
class D:public B,public C{};
int main(int arg, char *argv[]) {
D d;
cout<
联编:就是将模块或者函数合并在一起生成可执行代码的处理过程,(函数调用),按照联编所进行的阶段不同,可分为两种不同的联编方法:静态联编和动态联编
静态联编:指在编译阶段将函数实现和函数调用关联起来
例子:普通函数调用
动态联编:指在程序执行的时候才将函数调用和函数调用调用关联
动态联编是针对c++的多态的,c语言里全部都是静态联编
#include "iostream"
using namespace std;
class A {
public:
virtual void fun() {
cout << "fun " << endl;
}
};
class B:public A{
public:
void fun() override{
cout<<"B fun"<> b;
/// 主要看代码,这里不确定
switch (b) {
case 1:a = new A;
break;
case 2:a = new B;
break;
}
return 0;
}
#include "iostream"
#include "cstdlib"
using namespace std;
void fun(int a) {
if (0 == a) {
abort();// 异常终止
}
}
int main(int arg, char *argv[]) {
try {
// 本来想看个 /0 异常,很神奇
// int a = 10 / 0;
// cout << a << endl;
throw 0;
} catch (int b) {
cout << "异常捕获" << endl;
} catch (char c) {
cout << "异常捕获" << endl;
} catch (...) {
cout << "default erro" << endl;
}
return 0;
}
#include "iostream"
#include "cstdlib"
using namespace std;
class Out {
public:
int a;
Out() {
a = 12;
}
public:
class In {
public:
int b;
In() {
/// 内部类不能直接使用外部类的成员,还是需要对象的方式
Out o;
cout<
旧式类型转换:(type)vlaue
新式类型转换:static_cast
const_cast
dynamic_cast
reinterpret_cast