可变参数、static、对象大小和友元类、函数
知识点:
1. 可变参数
java中:int ...
c++:...
va_start(vp,count);
:将可变参数放到va_list vp中去,这个宏必须在使用 va_arg 和 va_end 之前被调用。int number = va_arg(vp,int);
: 获取可变参数,如果超出了可获取的范围默认就为0va_end(vp);
:结束了释放内存。
void sum(int count,...){// java:int ..., c++: ...
va_list vp;
// 可变参数开始方法, count 最后一个传递给函数的已知的固定参数。
va_start(vp,count);
int number = va_arg(vp,int);
cout << number <<endl;
// 读取下一个
number = va_arg(vp,int);
cout << number <<endl;
// 读取下一个,超出了默认是 0
number = va_arg(vp,int);
cout << number <<endl;
// 结尾,释放内存
va_end(vp);
}
int main(){
sum(5,1,2,4);
}
打印结果:
1
2
4
int sum(int count,...){// java:int ..., c++: ...
va_list vp;
// 可变参数开始方法, count 最后一个传递给函数的已知的固定参数。
va_start(vp,count);
int sum = 0;
for(int i = 0; i<count;i++){
int number = va_arg(vp,int);
sum += number;
cout << i << ":" << number << endl;
}
// 结尾,释放内存
va_end(vp);
return sum;
}
int main(){
int number = sum(4,1,2,4,0); // 7
cout << number << endl;
}
打印结果:
0:1
1:2
2:4
3:0
7
2. static 关键字
总结:
- 静态的属性定义时**
必须要初始化
** (实现)int Student::tag = 12;
- 静态 可以直接用类名去操作 ::
Student::tag += 12;
- 静态的方法只能去操作静态的属性或者方法
class Student{
public:
char* name;
int age;
//静态
static int tag; // 定义
Student(){
tag = 12; // 这里不算初始化
}
public:
static void change(){
tag += 12;
}
void change1(){
this -> change();
}
};
// 静态属性在 c++ 中必须要初始化,初始化必须这么写
int Student::tag = 12;
// 静态 可以直接用类名去操作 ::
// 静态的属性必须初始化(实现)
// 静态的方法只能去操作静态的属性或方法
int main(){
Student stu;
// stu.tag = 12;
// c++ 操作静态语法 ::
// Student::tag += 12;
// Student::change();
stu.change1();
cout <<Student::tag << endl;
}
打印结果:
24
3. 对象大小
- 对象的大小与结构体的计算方式类似
- static 静态变量和方法并没有算到类的大小中
- 栈,堆,全局(静态,常量,字符串),代码区 ,类的大小只与普通属性有关系
class A{
public:
double b;
int a;
char c;
};
class B{
public:
double b;
int a;
char c;
static double d;
};
class C{
public:
double b;
int a;
char c;
C(int a){
this->a = a;
}
public:
int getA(){
return this->a;
}
};
// 1. 对象的大小与结构体的计算方式类似
// 2. static 静态变量和方法并没有算到类的大小中
// 3. 栈、堆、全局(静态、常量、字符串),代码区,类的大小只与普通属性有关系
int main(){
cout << "A 的大小: " << sizeof(A) <<endl; // 16
cout << "B 的大小: " << sizeof(B) <<endl; // 16
cout << "C 的大小: " << sizeof(C) <<endl; // 16
C c1(12);
C c2(24);
cout << c1.getA() << endl;
cout << c2.getA() << endl;
}
打印结果:
A 的大小: 16
B 的大小: 16
C 的大小: 16
12
24
4. this 指针
this 指针:代表当前的对象,因为类的方法放在代码区,大家一起共享的,所以要有 this 做区分
5.const 修饰函数
const 在 () 之后主要用来限制 this 关键字
,this
的值和地址都不能修改
// this = const Student* const this
// 第一个 const : 常量指针, 代表值不能修改
// 第二个 const : 指针常量,代表指针的地址不能修改
void change() const { // const 在 () 之后主要用来限制 this 关键字
// this->age + = 12;
// this = (Student)0x0012;
}
6.友元函数
作用:友元函数是可以在外部访问其私有属性的
class Person
{
private:
int age = 0;
public:
// 如果有自己写构造函数,那么会默认覆盖无参的构造函数
Person(int age){
this->age = age;
}
// 友元函数的声明
friend void friend_change(Person *person, int age);
};
// 友元函数的实现
void friend_change(Person *person, int age){
// 修改一下 age 的值
// 在类的内部才能访问私有属性
// 如果该方法声明成友元函数那么是可以在外部访问其私有属性的
person->age = age;
}
int main(){
Person person = Person(24);
friend_change(&person,36);
cout << person.getAge() << endl;
}
打印结果:
36
注意:调用的时候不
使用 类名::
6.1 友元函数与普通函数的区别
- 友元函数:直接
方法名
调用。 - 普通函数:需要
对象名::
+方法名
调用
7.友元类
作用:友元类是可以在访问其附属类的私有属性
class ImageView
{
public: // B 是 A 的友元类
friend class Class;
private:
int a;
};
class Class
{
public:
ImageView aObj;
void changeA(int number){
aObj.a = number;
}
int getA(){
return aObj.a;
}
};
int main(){
Class b;
b.changeA(12);
cout << b.getA() << endl;
}
打印结果:
12