前言
本系列内容为程序媛学习C++时做的笔记。以代码为主,并备注了打印结果以及详尽的解释注释。希望对你有所帮助。
可变参数
#include <stdarg.h> // 可变参数的支持
void sum(int count, ...) {
va_list list;//可变参数的动作
//va_start参数1:可变参数开始的动作
//参数2:内部需要一个存储地址用的参考值,如果没有,内部它无法处理存放参数信息。
va_start(list, count);
// 到这里后:vp就已经有丰富的信息
//va_arg:取出可变参数的一个值
cout << va_arg(list, int) << endl;//9
cout << va_arg(list, int) << endl;//10
cout << va_arg(list, int) << endl;//22
cout << va_arg(list, int) << endl;//1985966061 (取不到后,会取系统值 乱码)
//关闭阶段
va_end(list);
}
调用:
sum(3, 9, 10, 22);
Static成员变量声明
/**
* 静态的总结:
* 1.可以直接通过类名::静态成员(字段/函数)
* 2.静态的属性必须要初始化,然后再实现(规则)
* 3.静态的函数只能取操作静态的属性和方法(Java)
*/
class Dog {
public:
//static int id =0; //不能直接声明赋值。静态变量要先声明,再赋值。
static int id;//先声明
void update() {
id = 10;
}
};
int Dog::id = 100;//再实现
int main() {
cout << "打印static的值:" << Dog::id << endl;//100
Dog dog;
dog.update();
cout << "打印static的值:" << Dog::id << endl;//10
return 0;
}
友元函数/友元类
友元函数:
class Dog {
private:
// C++中不像Java,Java有默认值, 如果你不给默认值,那么就是系统值 -64664
int age = NULL;//私有的age,外界不能访问
public:
int getAge() {
return age;
}
// 定义友元函数 (声明,没有实现)
friend void changeAge(Dog *dog, int age);
};
// 友元函数的实现,可以访问所以私有成员
void changeAge(Dog *dog, int age) {
// 默认情况下:不能修改 私有的age
//而友元函数就可以
dog->age = age;
}
int main() {
Dog dog;
cout << "打印age的值:" << dog.getAge() << endl;//0
changeAge(&dog, 101);
//Dog *p=&dog;//通过p拿不动私有的age
cout << "打印age的值:" << dog.getAge() << endl;//101
return 0;
}
友元类:
class Dog {
private:
int age = NULL;
// Java每个类,都会有一个友元类名为Class,此Class可以操作Dog私有成员(猜测)
friend class Class;//友元类
};
class Class {
private:
Dog dog;
public:
void changeDogAge(int age) { dog.age = age; }
int getDogAge() {
return dog.age;
}
};
int main() {
//类似Java的反射。拿到Class,就可以对私有成员变量赋值。
Class dogC;
dogC.changeDogAge(222);
cout << "打印age的值:" << dogC.getDogAge() << endl;//222
return 0;
}
或者:
class Dog {
private:
int age = NULL;
friend class Class;//友元类
};
class Class {
public:
void changeDogAge(Dog *dog, int age) { dog->age = age; }
int getDogAge(Dog dog) {
return dog.age;
}
};
int main() {
Dog dog;
Class dogC;
dogC.changeDogAge(&dog, 111);
cout << "打印age的值:" << dogC.getDogAge(dog) << endl;//111
return 0;
}
静态函数,友元函数,普通函数,构造函数,析构函数,拷贝构造函数
Pig.h
#ifndef CPPFIRST_PIG_H //如果没有这个宏
#define CPPFIRST_PIG_H //定义这个宏
class Pig {
private:
int age;
char *name;
public:
//静态成员声明
static int id;
//构造函数系列声明
Pig();
Pig(int age, char *name);
//析构函数
~Pig();
//拷贝构造函数
Pig(const Pig &pig);
// 普通函数 set get
int getAge();
char *getName();
void setAge(int);
void setName(char *);
//常量指针常量 只读
void showPig() const;//const在()后
// 静态函数的声明
static void changeTag();
//友元函数声明
friend void changeName(Pig pig, char *name);
};
#endif //CPPFIRST_PIG_H 关闭,结尾
Pig.cpp
#include "Pig.h"
//实现 构造函数
Pig::Pig() {}
Pig::Pig(int age, char *name) {}
//实现 析构函数
Pig::~Pig() {}
//实现 拷贝构造函数
Pig::Pig(const Pig &pig) {}
int Pig::getAge() {}
char *Pig::getName() {}
void Pig::setAge(int) {}
void Pig::setName(char *) {}
void Pig::showPig() const {}
///以下的实现写法特殊
int Pig::id = 100;//静态属性实现不需要static关键字
void Pig::changeTag() {}//静态函数实现不需要加static关键字
void changeName(Pig pig, char *name) {}//不需要 Pig:: ,只需要保证函数名(参数)
this的意义
class Student {
private:
char *name;
int age;
public:
static int id; // 先声明
}
// 再实现
int Student::id = 9527;
int main() {
Student student1;
student1.setAge(88); // 设置值的时候,它怎么知道是给student1的age设置值的?
student1.id = 880;
Student student2;
student2.setAge(99); // 设置值的时候,它怎么知道是给student2的age设置值的?
student2.id = 990;
Student::id = 666;
// 它怎么知道是获取student1的age
cout << " student1.getAge:" << student1.getAge() << endl; //88
// 它怎么知道是获取student2的age
cout << " student2.getAge:" << student2.getAge() << endl; //99
cout << "student1.id:" << student1.id << endl; //666
cout << "student2.id:" << student2.id << endl; //666
cout << "Student:::" << Student::id << endl; //666
return 0;
}
每次执行Student student的时候,会调用空参构造函数,在栈区开辟空间,暴露一个this指针。
student1和student2都有自己的this,通过不同的地址(this指针)找到对应的代码区域,进行setAge修改值。
id是static的,所有的student的id都共享一块静态区域。修改一个,其它的id值都跟着修改。
const 修饰函数时的 this
class Worker {
int id = NULL;
void change1() {
// 方法默认持有隐士的this【类型 * const this】
// 类型 * const 指针常量:代表指针地址不能被修改,但是指针地址的值是可以修改的
//this = 0x5689;//指针地址不能被修改 编译不通过 爆红
this->id = 111;//指针地址的值可以修改
}
void change2() const {//原理:修改隐士this的类型
// 默认现在:this 等价于 const Worker * const 常量指针常量(只读的)
//this = 0x5689;//地址不能改 编译不通过 爆红
//this->id = 111;//地址对应的值不能改 编译不通过 爆红
}
};