C++learning

//常量宏
#define PI 3.14
#define STU_COUNT 102

//宏模拟函数
#define ARRDY_SIZE(a) sezeof(a)/sizeof(a[0])

// 控制宏 declaration vs. definition
/* 头文件定义
#ifndef TEST_H
#define TEST_H

struct A{
int i;
};

#endif
*/

// 头文件中若要调用C中的函数
Cpp extern用法解析

/*
#ifdef __cplusplus
extern "C"
{
#endif

void fun_c();

#ifndef __cplusplus
}
#endif
*/

// C++ - A better C
1.overloading 重载 过载
同名函数,不同参数
2.默认参数 default parameter
void fun(int a, int b, int c = 3){}
3.占位参数
void fun(int);
void fun(int){}
大概率处理函数重载中既同名又同参的现象
want to learn more?

class Person{
	// access control
private:
	// data member
	int age;
	char *name;
public:
	// method(function method)
	void init(int age, char *name);
};
void Person::init(int age, char *name){
	this->age = age;
	this->name = name;
	/*
	init(int aage, char *name)
		age = aage;
		name = aname;
	此处又隐藏的 this 指针,两种写法等价
	*/	
}

C++Learning_2

析构函数释放类内一切函数申请的空间。
want to learn more?

reference 引用

引用必须初始化。

int i = 0;
int j = 1;
int& r = i;
cout << r << endl;	// print 0
r = j;
cout << i << endl;	// print 1

CPP-基础:关于引用

拷贝
Test t1(1, 2);
Test t2(t1);

注意此处为浅拷贝
assert
指针需要注意的点:
1.野指针(assert)
2.内存泄漏
3.返回局部变量地址
4.多重指针指向一个对象
深拷贝

// Override copy function
Test::Test(Test& t){
	this->i = t.i;
	this->j = (int *)malloc(sizeof(int));
	*j = *(t.j);
}

在函数参数传递中,若传值,则会有一步调用拷贝函数(无论是否重写)
建议不要pass by value
CPP-基础:C++拷贝构造函数详解

封装性剩余知识点

new = malloc + constructor
delete = destructor + free

// new出一个对象数组
Test *p = new Test[10];
delete []p;

const
const pass by address

void fun(const int *p){
	// 不可修改p指向的内容
}

如果要调用常量对象的函数,需要在声明时给函数加const修饰符.
以**基本类型(build-in type)**作为返回值的函数,默认是常量

int func(){} // 默认const
int m = func();
(func())++;//错误

常量指针和指针常量的区别
extern、static
C/C++中 extern 关键字详解
函数默认外连接(可见域:默认全局可见)
当函数被static修饰时,只能被本文件访问(只对本文件可见)
用static修饰的函数无多态,内部无this指针。
全局变量默认本文件可见(其他源文件调用需要extern外连接)
(全局变量可以作为函数间,文件间的通信)
(在类内定义静态static属性也可以进行多个类间从通信)
设计模式
构建型
结构型
行为型
operator overloading
运算符重载

class Account{
	private:
		int id;
		int balance;
	public:
		Account();
		void DepositMoney(int m);
		Account& operator +(int m);
		Account& operator ++();
		Account& operator ++(int);
};
Account::Account(){
	balance = 0;
	id = 1;
}
void Account::DepositMoney(int m){
	this->balance += m;
}
// operator overloading
Account& Account::operator +(int m){
	this->balance += m;
	return *this;
}
//前++
Account& Account::operator ++(){
	//TODO
	return *this;
}
//后++	!!注意此处返回一个对象
Account Account::operator ++(int){
	//TODO
	Account old = *this;
	this->balance += 1;
	return old;
}

int main(){
	Account a = new Account();
	a = a + 10;	// operator overloading
	retunr 0;
}

CPP-基础:运算符重载详解
new delete的重载,通常用于小型系统,以避免内存不足带来的new失败。

如果是有的系统,可能会抛异常,重载new可以捕获异常。
delete以后可能把指针自动置空等等~~

第6周

#include <iostream>
using namespace std;

class Borrower{
private:
	int id;
	char *name;
public:
	Borrower(int id);
	void borrowBook();
};
Borrower::Borrower(int id){
	this->id = id;
}
void Borrow::borrowBook(){}


class Student : public Borrower {
private:
	int studId;
public:
	Student(int id, int studID);
	void borrowBook();
	void bookVerificatoin();
};
Student::Student(int id, int studId) : Borrow(id){

}
void Student::borrowBook(){
	Borrower::borrowBook();	//调用父类的函数
}
void Student::bookVerification(){}

int main(){
	return 0;
}

inheritance & composition
1 reuse
2 why in~
3 is a and is like a
子类有父类共性,也有子类自己的特性
4 constructor initialization list(构造器初始化列表)
构造列表中的初始化顺序与列表中构造顺序不同,而是严格按照类中声明顺序。 for an instance:

class Exp{
	private:
		int i;
		int j;
	public:
		Exp(int aj);
};
Exp::Exp(int ai) : j(aj), i(j){}	 // Still, initialize 'i' first!

C++子类的构造函数自动调用父类的构造函数,且顺序为先父类后子类。
析构时先析子对象,再析父。
5 hiden(oveloading)
6 inhe vs. compsi
当事物概念比较抽象,继承和组合逻辑不能很好梳理时,可以先尝试组合
7 protected
为子类开启限权,子类可以访问
8 private inhe(私有继承)class Student : private Borrower
“官降一级”父类的public变为private,若将父类函数接口变为private则在子类对象中将对外界不可见。
但是由于原则:“永远不要削弱父类接口”,故私有继承一般无用。
9 multiple inhe(多重继承)
class Derived : public Base1, public Base2{};
多重继承带来的问题
可以利用单继承+多组合的模式来解决多重继承(?
组成(composition)用诸多小类来组成一个大类。for instance…

class Engin{};
class Car {
	private:
		Engin e;
		...
	public:
		...
};

多态

#include<instream>
using namespace std;

// upcasting 
// later binding vs. early binding
// polymorphism
// virtual constructor & destructor
// pure virtual
// abstract class ( interface in Java & C# )

class Pet{
	private:
		char *name;
		int age;
	public:
		void speak();
};
void Pet::speak(){};

class Cat{
	public:
		void speak();
};
void Cat::speak(){ cout << "i am a cat !" << endl}

class Dog{
	public:
		void speak();
};
void Dog::speak(){ cout << "i am a dog !" << endl}

void Needle(Pet pet){
	// binding
	pet.speak();
}

int main(){
	return 0;
}
upcasting 向上造型
binding 绑定

1.early binding 前绑定,先绑定
2.later(dynamic / runtime) binding 运行时绑定

将上述函数中Pet中的
void speak();
改为
virtual void speak();
另外在Needle中传递引用(传值会导致多态失效)
void Needle(Pet& pet);
此时可以使得其调用子类的speak函数

多态的前提是继承

关键字virtual关键字virtual会在类层次上创建一块“静态空间”(称为v-table虚函数表)用来存放virtual修饰的函数的入口指针,当创建含有virtual修饰的函数的对象时,此对象会多出8个字节(对于64位系统而言)(称为v-ptr虚指针),此8字节存放的是刚刚所说的那块“静态空间”的地址(即指向这块“静态空间”),所以通过pet.speak()访问子类重写的函数时候,会先通过这8字节找到这块静态控件再访问其中指向的函数。
C++虚函数的实现机制

virtual constructor & destructor构造和析构是否有多态

构造函数无需多态(virtual),而虚构函数往往需要进行多态(virtual)。

pure virtual 纯虚函数

virtual void speak() = 0;

抽象类

当一个类中含有一个或多个纯虚函数时,此类称之为抽象类abstract
抽象类无法创建对象,不允许实例化。
抽象类的第二个应用场景如下(用于行为串联)(接口):
多重继承

// 家族属性、行为串联
class Machine{};
class Animal{};
// 行为串联(在Java里可以理解为接口)
class FlyObject{
	public:
		virtual void fly() = 0;
};

class Plane : public Machine, public FlyObjct{
	public:
		void fly();
};
class Bird : public Animal, public FlyObject{
	public:
		void fly();
};

void scanFlyOb(FlyObject *ob){}

在Java里,有且只有一个父类,但可以实现多个接口,和C++里的多重继承实质上相同

接口:本不相关的两个类,因为行为相似而关联起来。

第8周

#include<iostream>
using namespace std;

// resuse
// exception
// namespace
// friend

template <calss T> class Stack{
	private:
		T pool[100];
		int top;
	public:
		// inline function 内联函数
		Stack():top(0){}
		void push(T v){
			pool[top++] = v;
		}
		T pop(){
			return pool[--top];
		}
};

int main(){
}
template class模板类
STL:standard template library

#include<vector>

vector<int> v;
for(int i = 0; i < 100; i++){
	v.push_back(i);
}

如果置位void*指针则可以放入任何类型的指针,但存在一个问题:
如何获取取出的指针的类型?从而还原其类型?

list<T> v

vector和list实现原理…

iterator迭代器

vector<int> v;
for(int i = 0; i < 10; i ++){ v.push_back(i);}

vector<int>::iterator it = v.begin();
while(it != v.end()){
	cout<< *it << endl;
	it++;
}

cpp:迭代器

exception 异常
void fun(int v) throw (int){
	if(v > 10) throw v;
}
int main(){
	try{
		fun();
	} catch (int e){
		cout << "exception ...caught"<< endl;
	} catch (...) {
		cout << "catch everything" << endl;
	}
}

C++函数后面加throw关键字简记
在C中可以尝试assert断言方便程序员调试(定义#define NDEBUG宏可以让程序中断言失效,相当于方便删去)

friend
class MyClass{
	private:
		int i;
	public:
		friend void func(MyClass &);
}

void func(Myclass& my){
	my.i = 10;
}

structclass的区别?…
设计模式…常见模式和用法

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值