可变参数
#include
#include // 可变参数的支持
using namespace std;
// Java的可变参数: int ...
// C++的可变参数写法:...
// count的第一个用处:内部需要一个 存储地址用的参考值,如果没有这个参数,内部他无法处理存放参数信息
void sum(int count, ...) {
va_list vp; // 可变参数的动作
// 参数一:可变参数开始的动作vp
// 参数二:内部需要一个 存储地址用的参考值,如果没有第二个参数,内部他无法处理存放参数信息
va_start(vp, count);
// 到这里后:vp就已经有丰富的信息
// 取出可变参数的一个值
int number = va_arg(vp, int);
cout << number << endl;
// 取出可变参数的一个值
number = va_arg(vp, int);
cout << number << endl;
// 取出可变参数的一个值
number = va_arg(vp, int);
cout << number << endl;
// 越界 系统值 乱码
// 取出可变参数的一个值 【取不到后,会取系统值 乱码】
number = va_arg(vp, int);
cout << number << endl;
// 关闭阶段
va_end(vp);
}
// 1.可变参数
int main() {
std::cout << "同学们大家好,我是Derry" << std::endl;
sum(546, 6,7,8);
return 0;
}
可变参数count变量的第二个用处
#include
#include // 可变参数的支持
using namespace std;
// Java的可变参数: int ...
// C++的可变参数写法:...
// count变量的第二个用处,用于循环遍历长度
void sum(int count, ...) {
va_list vp; // 可变参数的动作
// 参数一:可变参数开始的动作vp
// 参数二:内部需要一个 存储地址用的参考值,如果没有第二个参数,内部他无法处理存放参数信息
va_start(vp, count);
// 到这里后:vp就已经有丰富的信息
for (int i = 0; i < count; ++i) {
int r = va_arg(vp, int);
cout << r << endl;
}
// 关闭阶段(规范:例如:file文件一样 要关闭)
va_end(vp);
}
// 1.可变参数
int main() {
sum(3, 6,7,8); // 真实开发过程的写法
return 0;
}
static关键字==错误==示范
// 2.C++static关键字。 错误的写法
#include
using namespace std;
class Dog {
public:
char * info;
int age;
// 已经编译不成功,不允许这样初始化
// static int id = 9;
static int id;
Dog() {
// 运行报错
// id = 9;
}
static void update() {
// 运行报错
// id = 9;
}
void update2() {
// 运行报错
// id = 9;
}
};
int main() {
Dog dog;
Dog::update(); // 类名::可以调用静态函数
return 0;
}
static关键字==正确写法==
// 2.C++static关键字。 正确的写法
/**
* 静态的总结:
* 1.可以直接通过类名::静态成员(字段/函数)
* 2.静态的属性必须要初始化,然后再实现(规则)
* 3.静态的函数只能取操作静态的属性和方法(Java)
*/
#include
using namespace std;
class Dog {
public:
char * info;
int age;
// 先声明
static int id;
static void update() {
id += 100;
// 报错:静态函数不能调用非静态函数(Java)
// update2();
}
void update2() {
id = 13;
}
};
// 再实现
int Dog::id = 9;
int main() {
Dog dog;
dog.update2(); // 普通函数
Dog::update(); // 静态函数
dog.update(); // 对象名.静态函数(一般都是使用::调用静态成员,这种方式可以 知道就行)
cout << Dog::id << endl;
return 0;
}
this
#include // iostream.h 早期C++的方式
using namespace std;
class Student {
private:
char *name;
int age;
public:
static int id; // 先声明
public:
void setName(char *name) {
this->name = name;
}
void setAge(int age) {
this->age = age;
}
char *getName() {
return this->name;
}
int getAge() {
return this->age;
}
public:
// 默认的构造函数 栈区开辟空间 暴露 地址 == this指针 (和Java一致的思路)
};
// 再实现
int Student::id = 9527;
int main() {
//四大区:栈区、堆区、全局区(静态区、常量区、字符串区)、代码区
// ======= 常规使用下而已
Student student;
student.setAge(99);
student.setName("Derry");
cout << student.getName() << " , " << student.getAge()<< endl;
// ========== this 纠结 setAge在代码区,有多个副本,对应不用指针
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;
// 它怎么知道是获取student2的age
cout << " student2.getAge:" << student2.getAge() << endl;
cout << "student1.id:" << student1.id << endl;
cout << "student2.id:" << student2.id << endl;
cout << "Student:::" << Student::id << endl;
return 0;
} // main函数弹栈会 隐式代码:(栈区:delete student ..., 堆区需要自己手动delete)
const修饰函数的this意义何在
#include
using namespace std;
// 如果是面试C++岗位,会被回到,不然问不到
class Worker {
public:
char * name;
int age = NULL; // C++中不像Java,Java有默认值, 如果你不给默认值,那么就是系统值 -64664
// int * const 指针常量 指针常量【地址对应的值能改,地址不可以修改】
// const int * 常量指针 常量指针【地址可以修改,地址对应的值不能改】
// 纠结:原理:为什么可以修改age
// 默认持有隐式的this【类型 * const this】
// 类型 * const 指针常量:代表指针地址不能被修改,但是指针地址的值是可以修改的
void change1() {
// 代表指针地址不能被修改
// this = 0x6546; // 编译不通过,地址不能被修改,因为是指针常量
// 地址不可以修改
// this = 0x43563;
// 隐士的this
// 但是指针地址的值是可以修改的
// 地址对应的值能改
this->age = 100;
this->name = "JJJ";
}
// 默认现在:this 等价于 const Student * const 常量指针常量(地址不能改,地址对应的值不能改)
void changeAction() const {
// 地址不能改
// this = 0x43563;
// 地址对应的值不能改
// this->age = 100;
}
// 原理:修改隐式代码 const 类型 * const 常量指针常量
void showInfo() const {
// this->name = "";
// this->age = 88;
// 只读的
cout << "age:" << age << endl;
}
};
int main() {
return 0;
}
友元函数
// 老外:你是它的好朋友,那就可以拿私有成员给好朋友
#include
using namespace std;
class Person {
private: // 私有的age,外界不能访问
int age = 0;
public:
Person(int age) {
this->age = age;
}
int getAge() {
return this->age;
}
// 定义友元函数 (声明,没有实现)
friend void updateAge(Person * person, int age);
};
// 友元函数的实现,可以访问所以私有成员
void updateAge(Person* person, int age) {
// 默认情况下:不能修改 私有的age
// 谁有这个权限:友元(拿到所有私有成员)
person->age = age;
}
int main() {
Person person = Person(9);
updateAge(&person, 88);
cout << person.getAge() << endl;
return 0;
}
实际写法
#include
using namespace std;
#ifndef PIG_H // 你有没有这个宏(Java 宏==常量)
#define PIG_H // 定义这个宏
class Pig {
private:
int age;
char * name;
public:
// 静态成员声明
static int id;
// 构造函数的声明系列
Pig();
Pig(char *);
Pig(char *,int);
// 析构函数
~Pig();
// 拷贝构造函数
Pig(const Pig & pig);
// 普通函数 set get
int getAge();
char * getName();
void setAge(int);
void setName(char *);
void showPigInfo() const; // 常量指针常量 只读
// 静态函数的声明
static void changeTag(int age);
// 不要这样干
// void changeTag(int age);
// 友元函数的声明
friend void changeAge(Pig * pig, int age);
};
#endif // 关闭/结尾
#include "Pig.h"
// TODO ====================== 下面是 普普通通 常规操作 对象::
// 实现构造函数
Pig::Pig() {
cout << "默认构造函数" << endl;
}
Pig::Pig(char * name) {
cout << "1个参数构造函数" << endl;
}
Pig::Pig(char * name, int age) {
cout << "2个参数构造函数" << endl;
}
// 实现析构函数
Pig::~Pig() {
cout << "析构函数" << endl;
}
// 实现 拷贝构造函数
Pig::Pig(const Pig &pig) {
cout << "拷贝构造函数" << endl;
}
int Pig::getAge() {
return this->age;
}
char * Pig::getName() {
return this->name;
}
void Pig::setAge(int age) {
this->age = age;
}
void Pig::setName(char * name) {
this->name = name;
}
void Pig::showPigInfo() const {
} // 常量指针常量 只读
// TODO =============================== 静态 和 友元 注意点 自己理解
// 实现 静态属性【不需要增加 static关键字】
int Pig::id = 878;
// 实现静态函数,【不需要增加 static关键字】
void Pig::changeTag(int age) {
}
// 友元的实现
// 友元特殊:不需要关键字,也不需要 对象:: ,只需要保证 函数名(参数)
void changeAge(Pig * pig, int age) {
}
友元类
// 友元类 的 小故事 (ImageView 私有成员 可以通过Class来访问,但是Class操作的native C++代码)
// 下载 JDK native代码 研究 【自己去研究】
// ImageView 私有成员 你能访问它的私有成员吗 Class
#include
using namespace std;
class ImageView {
private:
int viewSize;
friend class Class; // 友元类
};
// Java每个类,都会有一个Class,此Class可以操作 ImageView私有成员(感觉很神奇)
class Class {
public:
ImageView imageView;
void changeViewSize(int size) {
imageView.viewSize = size;
}
int getViewSize() {
return imageView.viewSize;
}
};
int main() {
Class mImageViewClass;
mImageViewClass.changeViewSize(600);
cout << mImageViewClass.getViewSize() << endl;
return 0;
}