C++从入门到精通 C++98.11.14.17

C++进阶

    • 命名空间简介
    • auto、头文件防卫、引用、常量
    • 结构、权限修饰符、类简介
    • 新特性、内联函数、const详解
    • String类型
    • Vector类型
    • 类构造函数
    • 类的拷贝构造
    • 重载预算符 拷贝赋值 析构
    • 派生类
    • 友元函数
    • 左值右值
    • 对象移动、移动构造函数、移动赋值运算符
    • 类的类型转换
    • 模板

命名空间简介

namespace 命名控件 {

  .....

} 防止名字冲突在同一机制

	zhangsan.cpp
	namespace zhangsan {
		func();
	}
	main.cpp
	
	func();
	zhangsan::func();

auto、头文件防卫、引用、常量

引用

	int value = 7;	//不能用const 修饰  引用无法绑定到const类型上
	int &value1 = value;
	value1 = 12;
	std::cout << value1 << " " << value << std::endl;

	12 12

相同类型可绑 引用

constexpr

他也是一个常量的概念 编译时求值 先不管好了。。。

auto
自动类型推断

std::vector<int> num{ 1,2,4,5,6,4 };
	for (auto &i : num) {
		std::cout << i << std::endl;
	}
	for (auto i = num.begin(); i != num.end(); i++) {
		std::cout << *i << std::endl;
	}
	std::vector<int>::iterator k;
	for (k = num.begin(); k != num.end(); k++) {
		std::cout << *k << std::endl;
	}
	char *p = (char*)malloc(10 * sizeof(char));
	char q[] = "dcec";
	const char *q =  "3423";   //char* 是不可以修改的没在堆区分配内存 所以是指向常量区的  
	strcpy_s(p, 10, "hhee");
	p[0] = 'e';
	q[0] = 'e';
	std::cout << p << std::endl;
	std::cout << q << std::endl;
	char c[20];
	string s="1234";
	strcpy(c,s.c_str());
	c[0] = 'e';
	char str = new char[20];
	delete []str;

引用

#include 
class Time {
public:
	
	Time(int hour) : hour(hour) {

	}
	//引用把自己返回去了
	Time & get_time(int num);
	int get_hour() {
		return hour;
	}
private:
	int hour;
};
Time& Time::get_time(int num) {
	hour += num;
	return *this;
}
int main() {
	Time time = 3;
	std::cout << time.get_time(3).get_hour();
}

结构、权限修饰符、类简介

结构体

struct student {
	int age;
	char name[20];
	int func() {			//函数
		return 5;
	}
};
void func(student &stu) {
	stu.age = 1;
	strcpy_s(stu.name, 20, "204");
}
int main()
{	
	student stu;
	func(stu);
	std::cout << stu.age;
	std::cout << stu.func() << std::endl;
}

新特性、内联函数、const详解

inline
将函数的动作替换成函数的本体 嵌入 无需函数的压栈出栈
注意:内敛函数的定义是需要放在头文件的
代码膨胀 问题 内联函数尽可能小

const
上面字符串实例

String类型

略…

Vector类型

struct conf {
	conf(const char* name) {
		strcpy_s(filename, 20, name);
	}
	char filename[20];
};
conf* getinfo(std::vector<conf*>& conf_num, const char* temp) {
	for (auto i = conf_num.begin(); i != conf_num.end(); i++) {
		if (*(*i)->filename == *temp) {
			return *i;
		}
	}
	return nullptr;
}

int main()
{	
	conf* conf_one = new conf("abc");
	conf* conf_two = new conf("cde");
	std::cout << conf_one->filename << std::endl;
	std::cout << conf_two->filename << std::endl;

	std::vector<conf*> conf_num;
	conf_num.push_back(conf_one);
	conf_num.push_back(conf_two);
	conf* result = getinfo(conf_num, "abc");
	if (result != nullptr) {
		std::cout << "find";
	}
	for (auto i = conf_num.begin(); i != conf_num.end(); i++) {
		delete[] *i;
	}

}

类构造函数

explicit
修饰后 不支持隐式转换构造

#include 
class Time {
public:
	//
	Time(int hour) : hour(hour) {

	}
	inline int get_hour() {
		return hour;
	}
private:
	int hour;
};

int main() {
	Time time = 3;
	std::cout << time.get_hour();
}

static

class A {
public:
	static int a;
}

int A::a = 3;

类的拷贝构造

简单的写了下。。。

class Time {
public:
	Time(int hour,T peo) : hour(hour) {
		p = new T();
		*p = peo;
	}
	Time(const Time& time) : hour(time.hour){
		p = new T();
		*p = *(time.p);
	}
	int get_hour() {
		return hour;
	}
	T get_p(){
		return *p;
	}
	T* get_ptr() {
		return p;
	}
	~Time() {
		if (p) {
			delete []p;
		}
	}
private:
	T *p;
	int hour;
};

struct Stu {
	char* name;
	int* age;
};
int main() {
	Stu stu;
	stu.age = new int(8);
	stu.name = new char[20];
	strcpy_s(stu.name, 20, "xiaoming");
	//std::cout << *(stu.age) << std::endl;
	Time<Stu> time(1,stu);
	std::cout << time.get_hour() << std::endl;
	std::cout << time.get_p().age << std::endl;
	std::cout << time.get_ptr() << std::endl;
	//std::cout << time.get_hour() << std::endl;
	//std::cout << time.get_p() << std::endl;
	Time<Stu> time1(time);
	std::cout << time1.get_hour() << std::endl;
	std::cout << time1.get_p().age << std::endl;
	std::cout << time1.get_ptr() << std::endl;
}

C++从入门到精通 C++98.11.14.17_第1张图片

重载预算符 拷贝赋值 析构

Time<Stu> time1;
	time1 = time;
Time& operator=(Time& tmp) {
		p = new T;
		*p = *(tmp.p);
		hour = tmp.hour;
		std::cout << " 重载 ";
		return *this;
	}

派生类

子类共有继承父类 可以使用 父类的公有成员

#include 
#include 
#include "lisi.h"
class Time {
public:
	Time() {
		p = new int;
		hour = 0;
	}
	Time(int num) {
		p = new int;
		hour = num;
	}
	Time(int hour,int peo) : hour(hour) {
		this->p = new int;
		*p = peo;
	}
	Time(const Time& time) : hour(time.hour){
		this->p = new int;
		*p = *(time.p);
	}
	int get_hour() {
		return hour;
	}
	
	~Time() {
		if (p) {
			delete []p;
		}
	}
private:
	int *p;
	int hour;
};

class Time_son : public Time {
public:
	Time_son():Time(10) {

	}
	int get() {
		return get_hour();
	}
};

int main() {
	Time(10);
	Time_son T1;

	std::cout << T1.get();
}

友元函数

友元函数
友元函数声明在类内部 外界调用时 可以访问私有成员

class Time{
	friend int func();
private:
	int a;
}

int func(){
	return a;
}

int main(){
	func()
}

友元类
在类内定义友元类 可在友元内中访问其私有成员

class C;
class A {
	friend class C;
private:
	int val = 10;
};
class C
{
public:
	int call(A &a) {
		return a.val;
	}
private:

};

int main() {
	C c;
	A a;
	std::cout << c.call(a) << std::endl;
}

使用前向引用声明虽然可以解决一些问题,但它并不是万能的。需要注意的是,尽管使用了前向引用声明,但是在提供一个完整的类声明之前,不能定义该类的对象,也不能在内联成员函数中使用该类的对象

别踩坑。。。之前死活 进死胡同了
记住友元类的关系 是单向的 并且没有传递性

左值右值

临时变量可以用右值接 还有常量

int func() {
	int a = 9;
	std::cout << &a << std::endl;
	return a;
}
int main() {
	
	int && _a = func();
	std::cout << &_a;
}

对象移动、移动构造函数、移动赋值运算符

class A {
public:
	A() {
		val = new int(3);
	}
	A(A && a) noexcept {
		val = a.val;
		a.val = nullptr;
		std::cout << "移动" << std::endl;
	}
	int *val;
};

static A func() {
	A a; 
	return a;
}
int main() {
	
	A && _a = func();
	std::cout << *(_a.val);
	A a;
	A b(std::move(a));
}

如果类内有移动拷贝构造函数 系统会自动选择 最优的方式

类的类型转换

class A {
public:
//typedef void (tfC_B*) (int);
	using tfC_B = void(*)(int);
	A(int a = 0) : c(a) {
		
	}
	operator int() const {		//类型转换
		return c;
	}
	static void func(int v1) {
		int a = 3;
		std::cout << "func";
		//return a;
	}
	operator tfC_B() {
		return func;			//真的很怀疑有人这么用么。。。。
	}
public:
	int c;

};

int main() {
	
	A a(6);
	int k = a + 3;			//隐式
	int s = a.operator int() + 3;   //显示调用
	std::cout << k << std::endl;
	a(7);
}

模板

模板不一定是 指定类型 也可以是形参 比如那个“斐波那契数列”

template<typename T,int K,int S>
int cal(T a) {
	int result = (int)a + K + S;
	return result;
}
int main() {
	
	std::cout << cal<int,1, 4>(3);
	
}

你可能感兴趣的:(C++,进阶,c++,开发语言,算法)