C++:03.可变参数、static、对象大小和友元类、函数

1. 可变参数

java中:int ...
c++:...

  • va_start(vp,count);:将可变参数放到va_list vp中去,这个宏必须在使用 va_arg 和 va_end 之前被调用。
  • int number = va_arg(vp,int);: 获取可变参数,如果超出了可获取的范围默认就为0
  • va_end(vp);:结束了释放内存。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
3
1
2
4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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;
}

打印结果:

1
2
3
4
5
0:1
1:2
2:4
3:0
7

2. static 关键字

总结:

  1. 静态的属性定义时必须要初始化 (实现) int Student::tag = 12;
  2. 静态 可以直接用类名去操作 :: Student::tag += 12;
  3. 静态的方法只能去操作静态的属性或者方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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;
}

打印结果:

1
24

3. 对象大小

  1. 对象的大小与结构体的计算方式类似
  2. static 静态变量和方法并没有算到类的大小中
  3. 栈,堆,全局(静态,常量,字符串),代码区 ,类的大小只与普通属性有关系
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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;

}

打印结果:

1
2
3
4
5
A 的大小: 16
B 的大小: 16
C 的大小: 16
12
24

4. this 指针

this 指针:代表当前的对象,因为类的方法放在代码区,大家一起共享的,所以要有 this 做区分

5.const 修饰函数

const 在 () 之后主要用来限制 this 关键字,this 的值和地址都不能修改

1
2
3
4
5
6
7
// this = const Student* const this
// 第一个 const : 常量指针, 代表值不能修改
// 第二个 const : 指针常量,代表指针的地址不能修改
void change() const { // const 在 () 之后主要用来限制 this 关键字
// this->age + = 12;
// this = (Student)0x0012;
}

6.友元函数

作用:友元函数是可以在外部访问其私有属性的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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;
}

打印结果:

1
36

注意:调用的时候使用 类名::

6.1 友元函数与普通函数的区别

  • 友元函数:直接方法名调用。
  • 普通函数:需要对象名::+方法名 调用

7.友元类

作用:友元类是可以在访问其附属类的私有属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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;
}

打印结果:

1
12
-------------本文结束感谢您的阅读-------------
坚持原创技术分享,您的支持将鼓励我继续创作!
0%