1、可变参数
C++的可变参数,和Java的比起来感觉有点不太智能的样子。需要引入一个库来实现。
stdarg
在使用的过程中先定义一个va_list可变参数列表。
这时va_list是不可用的,需要调用方法 va_start 这个方法需要将va_list传进去,并且需要传递一个int 值,这个值初始值是任何值都没关系,但建议是和可变参数一块传进来,值建议为可变参数的长度,这样方便遍历可变参数。
使用va_arg 这个方法获取可变参数的值,两个参数 第一个参数 va_list,第二个参数,可变参数的类型。
最后,要使用va_end 来关闭va_list。
//可变参数
void testArgs(int count,...) {
cout <<"cout的值"<< count <<endl;
va_list vp; //可变参数的动作
//参数一 可变参数的动作
//参数二 需要一个int,stdarg 需要一个int 来记录 可变参数的位置
//内部需要一个存地址用的参考值,如果没有第二个参数,内部无法处理存放参数信息
va_start(vp,count);
//到这里后,vp就有丰富的值了;
//获取可变参数第一个值
int number = va_arg(vp,int);
cout << number <<endl;// 1
//获取可变参数的第二个值
int number2 = va_arg(vp,int);
cout << number2<<endl; //5
//获取可变参数的第三个值
int number3 = va_arg(vp,int);
cout << number3<<endl;//6
//count 的第二个作用 循环 和上面的写法 二选一
// for (int i=0;i<count;++i) {
// int number3 = va_arg(vp,int);
// cout << number3<<endl;//6
// }
//关闭
va_end(vp);
}
int main () {
testArgs(3,1,5,6,8,1,5);
return 0;
}
2、static 关键字
在类中可以定义static 修饰的 成员变量,但是不能在定义的地方进行,初始化。编译都不会通过。不允许这样干。
在构造方法里也不允许初始化。编译成功,运行报错。
静态函数里赋值。也不可以。
错误写法
class Person {
public:
char * name;
int age;
static int id =9;//会报错 static data member cannot have an in-class initializer
Person() {
id =10;//会报错
}
static void updateAge() {
id =10;//会报错
}
void updateAge2() {
id= 15;//会报错
}
};
正确写法
class Person {
public:
char * name;
int age;
//先声明
static int id;
Person() {
id =10;//可以修改
cout<< id <<endl;
}
static void updateAge() {
id =10;//可以修改
}
void updateAge2() {
id= 15;//可以修改
}
};
//再实现
int Person::id = 10;
int main(int argc, char *argv[]) {
Person person;
person.updateAge2();
Person ::updateAge();
return 0;
}
int Person::id = 10;没有这句代码,在类中的 static id,是没有在静态区中开辟空间的,也就是没有引用可以找到它的。所以你初始化就会报错。int Person::id = 10这句代码执行了,静态区里才会有一个 别名为id 数据类型为 int 的数据存在的。
可以直接通过类名::静态成员(字段函数)调用。也可以通过对象.静态方法这种在C++中是支持的,但是不建议这样用。推荐规范写法 冒冒的写法。
静态的属性必须要初始化,然后再实现。(规则)
静态的函数只能去操作静态的属性和方法。和Java一样。
3、辨析常量指针,指针常量,常量指针常量
const int * numberP1;
常量指针 不允许修改常量指针存放地址所对应的值,允许重新指向常量指针存放的地址。
int * const numberP2;
指针常量 允许修改指针常量存放地址所对应的值。不允许重新指向指针常量存放的地址
const int * cosnt numberP3;
常量指针常量 不允许修改常量指针常量存放地址所对应的值。不允许重新指向常量指针常量存放的地址
4、this 关键字
为什么需要this关键字?
伪代码
main {
Student stu1;
stu1.setAge(8);
Student stu2;
stu2.setAge(10);
}
问题一: stu2.setAge是怎么知道给stu2这个对象的age 赋值的呢?
Student 在执行构造函数时,会在栈区开辟一块空间。然后会存放一个this(指针),这个指针指向代码区存放函数体的地方。这样就能精确的将值赋给stu1 和stu2了。
问题二 const 修饰函数屁股,有什么效果?
class Person {
public:
char * name;
int age;
void updateAge2(){
//此时this Student *const this; 指针常量, 可以修改其地址对应的值。
//不能修改this的值(地址)
this->age =10;
//this =0x2233;//不能修改
}
//const 修饰函数屁股
void updateAge3() const{//成员变量只读
//此时this cosnt Student *const this 常量指针常量
//在这个方法里不能修改成员变量的值,
//this->age =10;//不能修改
// this =0x446;//不能修改
}
};
5、友元函数、友元类
在C++的类中,有私有成员,我们是不能访问的。自己的宝贝,只能自己玩,,别人不能玩的。自己的宝贝让别人玩,你放心么。但是你想玩我的宝贝怎么办,只能成为我的好基友才可以哦。不是普普通通的好基友。是超越了亲情和爱情的好基友才可以玩我的宝贝。所以C++ 有了友元函数。
class Person {
private:
int age= 0;
//声明友元函数,在类中只声命不实现
friend void updateAge(Person * personP);
};
void updateAge(Person * personP) {
//可以拿到所有私有成员
personP->age;//这样就可以玩Person的宝贝了
}
int main(int argc, char *argv[]) {
Person person;
updateAge(&person);
return 0;
}
private:
int age= 0;
//声明友元函数,在类中只声命不实现
friend void updateAge(Person * personP);
friend class Class;//声明友元类
};
//在Java中每个类都会有一个Class ,这个Class 可以操作对象的私有成员
class Class {
Person person;
void changeAge(int age) {
person.age =age;//可以修改
}
};